У меня есть 2 CPP файлы, каждый из которых объявлено 1 класса +-функция + 1 статического объекта:Тот же код на C++, другая опция ссылки приводит к разному поведению?
$ cat mya.cpp
#include<stdio.h>
struct A{
A(){printf("%s\n",__FUNCTION__);}
};
void fa(){printf("%s\n",__FUNCTION__);}
static A s_obj;
$ cat myb.cpp
#include<stdio.h>
struct B{
B(){printf("%s\n",__FUNCTION__);}
};
void fb(){printf("%s\n",__FUNCTION__);}
static B s_obj;
Тогда главная функция называет "FB", но не "ФА".
$ cat nm.cpp
void fb();
int main()
{
fb();
return 0;
}
Я попытался собрать и связать эти файлы разными способами:
g++ -c mya.cpp -fPIC
g++ -c myb.cpp -fPIC
ar -rvs libmya.a mya.o
ar -rvs libmyb.a myb.o
ar -rvs libmystatic.a mya.o myb.o
g++ --shared -o libmyshare.so mya.o myb.o
g++ --shared -o libadyn.so mya.o
g++ --shared -o libbdyn.so myb.o
g++ nm.cpp -o use1StaticLib -lmystatic -L.
g++ nm.cpp -o use2StaticLib -lmyb -lmya -L.
g++ nm.cpp -o use1DynamicLib -lmyshare -L.
g++ nm.cpp -o use2DynamicLib -ladyn -lbdyn -L.
g++ nm.cpp -o useDirect mya.cpp myb.cpp
Тогда я нашел 5 исполняемые файлы имеют различное поведение:
$ ./useDirect
A
B
fb
$ ./use1DynamicLib
A
B
fb
$ ./use2DynamicLib
B
fb
$ ./use1StaticLib
A
B
fb
$ ./use2StaticLib
B
fb
Тот же код, другое поведение, как я не могу смутить?
Кажется, я нашел какую-то подсказку, если mya.cpp и myb.cpp упакованы в другой файл .a/.so, тогда «A s_obj» не сконструирован. Зачем? Конструктор A имеет побочный эффект, и я не указываю никакой оптимизации -O.
Если причина в том, что «A_obj» - это объект, который не используется, поэтому не связан, то «B s_obj» не используется основной функцией, почему она всегда построена?
Нужно слышать объяснения ваших экспертов!
На глобальных конструкторов нельзя полагаться, но вы уже это знали. Это просто неопределенно, вероятно, так как есть как язык, так и правила os. – Jojje