Initializing a static object when linking to a static library

What are the rules for initializing a static object declared in another shared library? For example, consider the following:

X.hpp file:

struct X { X (); static X const s_x; }; struct Y { Y (X const &) {} }; 

X.cpp file:

 #include "X.hpp" #include <iostream> X::X () { std::cout << "side effect"; } X const X::s_x; 

I compiled X.cpp in the libX.a static library, and I tried to link the following executable file to it (main.cpp file):

 #include "X.hpp" int main () { (void)X::s_x; // (1) X x = s_x; // (2) Y y = s_x; // (3) } 

only with (1) or (2), nothing happens. But if I add (3), the static object is initialized (i.e., a "side effect" is printed). (I am using gcc 4.6.1).

Is there any way to predict what will happen here?

I do not understand how command (2) does not force the X::s_x create by default, whereas (3) does.

EDIT: build commands:

 g++ -c X.cpp g++ -c main.cpp ar rcs libX.a Xo g++ -o test main.o -L. -lX 
+6
source share
1 answer

By default, on many platforms, if your program does not refer to any characters from the specified object file in the static library, the entire object file (including static initializers) will be deleted. Therefore, the linker ignores Xo in libX.a because it looks like it is not in use.

There are several solutions here:

  • It is independent of the side effects of static initializers. This is the most portable / easy solution.
  • Introduce some fake dependency on each file by referencing a dummy symbol so that the compiler does not look (for example, saving the address in a globally visible global).
  • Use some platform-specific trick to save the objects in question. For example, on Linux, you can use -Wl,-whole-archive ao ba -Wl,-no-whole-archive .
+4
source

Source: https://habr.com/ru/post/896753/


All Articles