5

Consider the following complete program consisting of two TU's:

// 1.cpp
bool init() { /* ... */ }
const auto _{init()};

// 2.cpp
int main() {}

Question: is there any guarantee that _ is initialized at some point (I do not care when)?

Now consider the program consisting of one TU:

// 1.cpp
bool init() { /* ... */ }
const auto _{init()};
int main() {}

Note that _ is not odr-used.

However, can main(), in the second case, be said to be odr-used, since it gets (sort of) "referred by the implementation" as it gets called when the program is run?

And if main() is odr-used, does this imply that _ is guaranteed to be initialized even if it's not odr-used?

EDIT:

This is what en.cppreference.com says about Deferred dynamic initialization:

If no variable or function is odr-used from a given translation unit, the non-local variables defined in that translation unit may never be initialized (this models the behavior of an on-demand dynamic library)

Can you answer my questions considering the above when reading my two examples?

Martin
  • 9,089
  • 11
  • 52
  • 87
  • What do you mean by "deferred dynamic initialization"? I can't see why there would be anything dynamic or deferred going on here. –  Jan 19 '18 at 00:14

2 Answers2

5

It's supposedly the linker's job to collate all objects with static storage-duration from all translation units for initialization during program initiation - however, its a bit more than that, the guarantee is that those objects will be initialized before the use of any function within that translation unit.

basic.start.static/1: Variables with static storage duration are initialized as a consequence of program initiation....

Also see:

basic.stc.static/2: If a variable with static storage duration has initialization or a destructor with side effects, it shall not be eliminated even if it appears to be unused...

WhiZTiM
  • 21,207
  • 4
  • 43
  • 68
  • @Martin, no, you aren't missing anything. This is true. This happened to me before when using CppUnit for testing. Essentially my tests in different TUs weren't running on some platform/compilers, adding a static variable to all test TU's and using `extern` to modify it solved my problem. – WhiZTiM Jan 19 '18 at 00:59
  • Ok. So what is the answer to my question? I am confused. – Martin Jan 19 '18 at 01:05
  • @Martin, Yes, if you do not call any function or make any cross-reference to any variable in some translation unit X, the static objects in X may never get initialized. See [Prevent Linker from optimizing startup code](https://stackoverflow.com/questions/1300778/how-to-prevent-the-linker-from-optimizing-away-startup-code?noredirect=1&lq=1) – WhiZTiM Jan 19 '18 at 01:07
  • So defining _ where main() is defined is a way to have the guarantee that _ is initialized? – Martin Jan 19 '18 at 01:10
  • @Martin, defining it in the translation unit where `main()` is would invoke [basic.start.dynamic/4](http://eel.is/c++draft/basic.start.dynamic#4): which essential provides the guarantee you seek if the initialization of such static object has side effects – WhiZTiM Jan 19 '18 at 01:16
2

The object _ is guaranteed to be initialized. According to [basic.start.static]/1,

Variables with static storage duration are initialized as a consequence of program initiation. Variables with thread storage duration are initialized as a consequence of thread execution.

In case you were wondering whether that could be read only as guaranteeing that static initialization shall occur, and not guaranteeing that dynamic initialization shall occur, see [dcl.dcl]/11,

A definition causes the appropriate amount of storage to be reserved and any appropriate initialization (11.6) to be done.

Thus, all initialization required by the semantics of the initializer {init()} shall be performed on the object _.

As usual, the as-if rule applies. If init() has any observable behaviour, such behaviour must occur. It has any side effects that affect observable behaviour, such side effects must occur.

The fact that _ is not odr-used is irrelevant. The tangent about main is irrelevant too.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312