Method to specify initialization order across translation units?

Andrew Haley aph@redhat.com
Wed Aug 5 20:50:00 GMT 2015


On 05/08/15 17:47, Jeffrey Walton wrote:
> I'm catching an intermittent failure due to initialization order
> across translation units. The code is for a C++ library that offers
> both a static archive and a shared object.
> 
> My first thought was to provide an accessor function and make the
> global a static local. That did not work because the order of
> construction and destruction was not right. It resulted in a crash in
> a destructor because an object disappeared too soon. My second thought
> was init_priotrity and __attribute__ (constructor) (and friends), but
> I know from experience that does not work across translation units.
> 
> My third though was a linker script, and then I came across "Replace
> .ctors/.dtors with .init_array/.fini_array on targets supporting them"
> (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=46770#c96) and "collect2
> breaks link order control"
> (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53068). If I am reading
> the reports correctly, then a linker script is not the tool for the
> job.
> 
> We also thought about adding a global.cpp file, but we are not sure it
> will meet goals because of third party programs, the static archive,
> and the interactions during linking.
> 
> The static archive seems to be the trickiest case because of the
> interaction with third party programs. The shared object seems to be
> an easier problem because its fully linked, and does not interact with
> program linking. (Open question: does LTO affect this?).
> 
> Are there any methods to specify initialization order across
> translation units? If so, what is it (or are they)?

init_priority (priority)

    In Standard C++, objects defined at namespace scope are guaranteed
to be initialized in an order in strict accordance with that of their
definitions in a given translation unit. No guarantee is made for
initializations across translation units. However, GNU C++ allows
users to control the order of initialization of objects defined at
namespace scope with the init_priority attribute by specifying a
relative priority, a constant integral expression currently bounded
between 101 and 65535 inclusive. Lower numbers indicate a higher
priority.

    In the following example, A would normally be created before B,
but the init_priority attribute reverses that order:

              Some_Class  A  __attribute__ ((init_priority (2000)));
              Some_Class  B  __attribute__ ((init_priority (543)));

    Note that the particular values of priority do not matter; only
their relative ordering.

Andrew.



More information about the Gcc-help mailing list