Inspired by this question.
We know that global variables with non-constexpr
initializers undergo two different "initializations":
Which of those initializations starts the variable lifetime? [basic.life]
is being surprisingly unhelpful:
The lifetime of an object ... begins when: ... its initialization (if any) is complete
I see several options:
(1) Would make the most sense, but it would make the static initialization of an object that will later be dynamically initialized mostly useless.
(2) Would have interesting effects. E.g. the static init order fiasco is suddenly not UB (by itself) anymore.
(3) Would be very weird.
In compiled languages, global variables are generally static variables, whose extent (lifetime) is the entire runtime of the program, though in interpreted languages (including command-line interpreters), global variables are generally dynamically allocated when declared, since they are not known ahead of time.
@heksesang: Yes, it happens only in this constellation. If I make both A and B static libs or both shared libs, I do not face the issue (c'tor of A is run only once). However, I would expect the linker to recognize and eliminate duplicate symbols and init calls.
The difference between static initialization and dynamic initialization: A static initialization in java is a particular block that is made to run before the main () method in java whereas dynamic initialization refers to the initiation of the project during the rum time.
Dynamic initialization of object refers to initializing the objects at run time i.e. the initial value of an object is to be provided during run time. Dynamic initialization can be achieved using constructors and passing parameters values to the constructors.
This is because the values of these variables must be known before the execution starts. An error will be generated if the constant values are not provided for global and static variables. A program that demonstrates the initialization of global and static variables is given as follows.
If constants are not used to initialize the global and static variables, this will lead to an error. A program that demonstrates this is as follows. The above program leads to a error “initializer element is not constant”.
An error will be generated if the constant values are not provided for global and static variables. A program that demonstrates the initialization of global and static variables is given as follows. The output of the above program is as follows.
Indeed, the standard is vague by not specifying how exactly the quoted rule "initialization (if any) is complete" applies to multiple stages of initialization, each of which being referred to as "initialization". And this leaves room for multiple interpretations.
This footnote (non-normative) implies that the lifetime begins only after dynamic initialisation is complete:
[basic.life]
Before the lifetime of an object has started but after the storage which the object will occupy has been allocated 26 ...
26 For example, before the dynamic initialization of an object with static storage duration ([basic.start.dynamic]).
As the other answer makes its argument solely on a non-normative footnote, I will offer a counter-argument based on non-normative note. Not that I have any belief in this interpretation over the other, but I think the standard is in non-normative conflict here, at best.
Note 2 of [basic.start.static]/3 gives an example of unspecified, not undefined, behavior where an implementor (adhering to [basic.start.static]/3) is permitted to perform initialization of a static/thread storage duration variable even if it is not required to be initialized during static initialization (could be during dynamic initialization). The key here being the note's example of why the value of obj1
is unspecified: namely that the value of the object which is used to initialize it may be "fully initialized" or "merely zero-initialized":
[Note 2: As a consequence, if the initialization of an object
obj1
refers to an objectobj2
potentially requiring dynamic initialization and defined later in the same translation unit, it is unspecified whether the value ofobj2
used will be the value of the fully initializedobj2
(becauseobj2
was statically initialized) or will be the value ofobj2
merely zero-initialized. For example,inline double fd() { return 1.0; } extern double d1; double d2 = d1; // unspecified: // either statically initialized to 0.0 or // dynamically initialized to 0.0 if d1 is // dynamically initialized, or 1.0 otherwise double d1 = fd(); // either initialized statically or dynamically to 1.0
— end note]
Particularly the comment from the example code snippet:
[d2] either statically initialized to
0.0
or dynamically initialized to0.0
ifd1
is dynamically initialized, or1.0
otherwise.
Implying that the "otherwise" case, namely where d1
is (dynamically) initialized from the "merely zero-initialized" d2
is not undefined.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With