Я воспроизвел это с g++ (Debian 7.3.0-5)
, а также g++ (GCC) 9.0.0 20180902 (experimental)
.
Интересно, что это не получается:
$ g++ singleton.cpp main.cpp && ./a.out
beforeFunction
Segmentation fault
, но это работает, как и ожидалось:
$ g++ main.cpp singleton.cpp && ./a.out
beforeFunction
singleton ctor
Как правильно сказал Акорн, механизм iostream
/ std::cout
не был должным образом инициализирован к тому времени, когда вы вызвали одноэлементный конструктор.Это происходит потому, что в main.o
(и only main.o
) есть специальный код, который вызывает std::ios_base::Init::Init()
.И только потому, что main.cpp
имеет постороннее #include <iostream>
.
Как это исправить?
Лучшее решение - вообще не использовать __attribute__((constructor))
.В вашем случае нет причин делать то, что вы делаете.Сделайте это вместо:
// singleton2.cpp
#include<iostream>
using namespace std;
class singleton{
public:
singleton(){cout<<"singleton ctor\n";}
};
static singleton obj;
С приведенным выше кодом работает любой порядок связывания:
$ g++ main.cpp singleton2.cpp && ./a.out
singleton ctor
$ g++ singleton2.cpp main.cpp && ./a.out
singleton ctor
Если вы настаиваете на использовании __attribute__((constructor))
, то убедитесь, что на вашем компьютере стоит main.o
линия связи перед любым другим объектом, который может использовать iostream
s.