Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

If a global variable is initialized twice (statically, then dynamically), which initialization starts its lifetime?

Inspired by this question.

We know that global variables with non-constexpr initializers undergo two different "initializations":

  • First, the "static initialization", which zero-initializes them.
  • Second, the "dynamic initialization", which uses the user-provided initializer.

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. The last initialization starts the lifetime.
  2. The first initialization starts the lifetime.
  3. Each successive initialization destroys the existing object and creates a new one in its place.

(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.

like image 475
HolyBlackCat Avatar asked Jun 15 '21 17:06

HolyBlackCat


People also ask

What is the lifetime of a global variable?

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.

Can static variable be initialized twice?

@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.

What is static and dynamic initialization?

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.

What is dynamic initialization variable?

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.

Why must the values of global and static variables be initialized?

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.

What happens if a constant is not used to initialize variables?

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”.

What happens if the constant values are not provided for global variables?

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.


2 Answers

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]).

like image 108
eerorika Avatar answered Oct 13 '22 12:10

eerorika


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 object obj2 potentially requiring dynamic initialization and defined later in the same translation unit, it is unspecified whether the value of obj2 used will be the value of the fully initialized obj2 (because obj2 was statically initialized) or will be the value of obj2 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 to 0.0 if d1 is dynamically initialized, or 1.0 otherwise.

Implying that the "otherwise" case, namely where d1 is (dynamically) initialized from the "merely zero-initialized" d2 is not undefined.

like image 43
dfrib Avatar answered Oct 13 '22 11:10

dfrib