__attribute __ ((init_priority (X))) in GCC

I use __attribute__((init_priority(X))) in GCC as follows:

 Type1 __attribute__ ((init_priority (101))) name1 = value1; Type2 __attribute__ ((init_priority (102))) name2 = value2; 

in different source files. Say file1.cpp and file2.cpp. If I use this in the same library, it works as expected, name1 initializes to name2, but if I use it in different libraries, the initialization order is not expected. I read in the gcc documentation that this should work in different libraries, as I expect, to determine the initialization order. Is there something wrong with the way I use it? Did you have the same problem?

PS: refactoring is not a solution to this problem, because I have to migrate a very large project from Visual Studio.

+4
source share
5 answers

The gcc documentation (gcc 4.4) states:

`init_priority (PRIORITY) '

In standard C ++, objects defined in the namespace area are guaranteed to be initialized in the order strictly corresponding to the order of their definition in a given translation unit. There are no guarantees for initialization between translation units. However, GNU C ++ allows users to control the initialization order of objects defined in the namespace area with the init_priority attribute by setting a relative PRIORITY, the constant integral expression is currently limited from 101 to 65535 inclusive. Lower numbers indicate higher priority.

Nowhere is there any indication of how this applies to libraries, especially shared libraries. I would expect the static libraries (libxyz.a) to work the same way as individual object files in this regard, since they are just a collection of object files, and the wording of the documentation assumes that it works through translation units (i.e. .With another object files).

However, shared libraries are actually executable files in their own right --- within this shared library, initialization is performed in the specified order, but shared libraries are generally initialized in the order specified by the dynamic loader, i.e. liba. therefore, it loads before or after libb.so based on the bootloaderโ€™s ordering criteria, and the init_priority attribute cannot affect this ordering.

+5
source

If your library is dynamic, i.e. .so, not .a, then ld will affect the order of things, and gcc can only control the init order within the same binary ELF file (which will be the sum of all .o and .a) .

0
source

If you want your things to be initialized in order, try creating an init function with __attribute__((constructor (priority))) .

0
source

Using the GNU linker, your shared libraries will be initialized one after the other in the order of their dependencies, and not in parallel. This means that if your binary depends on a shared library, the shared library is initialized before dynamic initialization in your binary starts.

0
source

Are all the objects in question in the same area of โ€‹โ€‹the namespace (I assume it is global)? I did not see any guarantees in the GCC documentation that it was required to work in different libraries (although this would make sense for the linker).

Despite your last comment, I'm still going to offer refactoring. If you have control over the code to use __attribute__ , you can at least use the shell instance function, which uses static local to initialize. This will require some code change, but in general it should be done in semi-automatic mode. See http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.13 .

Also note that if you fix / reorganize the code, you do not run the risk of paying the compiler / update to the VS compiler, suddenly breaking the code, possibly in an unobvious way.

0
source

All Articles