19

Example:

struct Foo { Foo() { printf("foo\n"); } };
static Foo foo;

__attribute__((constructor)) static void _bar() { printf("bar\n"); }

Is it deterministic wether foo or bar is printed first?

(I hope and would expect that constructors of static objects are always executed first but not sure and GCCs doc about the constructor attribute doesn't say anything about it.)

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
Albert
  • 65,406
  • 61
  • 242
  • 386
  • Where do you use such kind of compiler features?? – AlexTheo Dec 09 '11 at 15:47
  • @AlexTheo: That is quite common. See e.g. . You usually use it everytime you want to initialize something. – Albert Dec 09 '11 at 15:51
  • Actually I prefer something like static const bool _isInitialized and making an private initialization function with which I initialize my object like const bool MyClass::_isInitialized = initFunction(); But these is only for objects which I like initialize first of all. Otherwise constructor should do a job. – AlexTheo Dec 09 '11 at 16:10
  • @AlexTheo That approach doesn't work in C. Sure you can use a constructor in C++, but this has the same effect as a static initializer in C. – nevelis Sep 28 '12 at 06:08
  • @nevelis we are talking about c++!!! – AlexTheo Sep 28 '12 at 10:24
  • @AlexTheo Indeed you are :D pardon the early morning vision, I somehow ended up here looking for a C solution and must've misread the title.. However my "That approach doesn't work in C" was to answer your "Where do you use such kind of compiler features??" question. – nevelis Sep 30 '12 at 23:15

2 Answers2

15

foo will be printed first, as the objects are initialized in the order of their declarations. Run and see:

By the way, __attribute__((constructor)) is not Standard C++. It is GCC's extension. So the behavior of your program depends on how GCC has defined it. In short, it is implementation-defined, according to it foo is printed first.

The doc says,

The constructor attribute causes the function to be called automatically before execution enters main (). Similarly, the destructor attribute causes the function to be called automatically after main () has completed or exit () has been called. Functions with these attributes are useful for initializing data that will be used implicitly during the execution of the program.

You may provide an optional integer priority to control the order in which constructor and destructor functions are run. A constructor with a smaller priority number runs before a constructor with a larger priority number; the opposite relationship holds for destructors. So, if you have a constructor that allocates a resource and a destructor that deallocates the same resource, both functions typically have the same priority. The priorities for constructor and destructor functions are the same as those specified for namespace-scope C++ objects (see C++ Attributes).

I think the text in bold implies, the objects are initialized in the order of their declarations, as I said before, which is pretty much confirmed by online demo also.

I guess you would also like to read this:

If you want to control/alter the initialization order, you can use init_priority attribute, providing priority. Taken from the page:

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

Here, B is initialized before A.

Community
  • 1
  • 1
Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • Hm, all comments were deleted? How is that possible. So, here is my comment again: The interesting bit for me was this information together with the last link, esp. this: *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.* – Albert Dec 08 '11 at 18:55
  • Actually, I just tested it on another example, and it doesn't seem to be the case there. – Albert Dec 09 '11 at 14:01
  • @Albert: Post the code. The actual code, without changing it a bit. Also post the output you get. – Nawaz Dec 09 '11 at 14:04
  • 2
    This answer is wrong. As per the [docs](https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-Function-Attributes): "The priorities for constructor and destructor functions are the same as those specified for namespace-scope C++ objects (see C++ Attributes). _However, at present, the order in which constructors for C++ objects with static storage duration and functions decorated with attribute constructor are invoked is unspecified._" Hence, as @Albert mentions in his answer, the output is non-deterministic. – ghd Dec 17 '19 at 03:20
3

It isn't defined by the standard, but here is my experiment https://github.com/SanSanch5/static-initialization-order-example

The output on gcc-9:

CFoo constructed
dll constructor
CBaz constructed
CBar constructed
foo
dll destructor
CBar destructed
CBaz destructed
CFoo destructed

The output on clang-12:

CFoo constructed
dll constructor
CBaz constructed
CBar constructed
foo
CBar destructed
dll destructor
CBaz destructed
CFoo destructed

So, the dll constructor is being called before static initialization, but as you can see, the destruction is slightly different on gcc and clang. But initializing a static object inside a dll constructor experimentally proves its destruction after the other static objects. But it's non-standard so not reliable.