When is the storage location of static variables in C++ determined?

Viewed 128

I have the following simple program:

int main()
{
    int x = 5;
    static int y = x;
    return (0);
}

Compiling it with gcc, it produces error for the line static int y = x; since "initializer element is not constant". I assume this is due to y being a static variable, whose storage location (data/bss) and initial value need to be known at compile time.

However, when compiling with g++, I don't get any errors and the program runs well (printing y prints 5).

My questions are:

  1. Is my assumption correct?
  2. If so, how come it is possible to make such initialization to a static variable in c++?
3 Answers

Your program is well-formed in C++ as local variables with static storage duration are initialized not during startup (with some exceptions for constant expressions; not applicable in this example) but at the first time control passes through their declaration, at which point the initializer expression, containing the local non-static variable x, is readily available.

Citing cppreference / Storage duration - Static local variables [emphasis mine]

Variables declared at block scope with the specifier static or thread_local (since C++11) have static or thread (since C++11) storage duration but are initialized the first time control passes through their declaration (unless their initialization is zero- or constant-initialization, which can be performed before the block is first entered). On all further calls, the declaration is skipped.

Static initialization in C, however, does not follow the same rules; from cppreference / C language - Initialization:

When initializing an object of static or thread-local storage duration, every expression in the initializer must be a constant expression or string literal.

Thus your program is ill-formed in C.

In C++, static local variables are initialized only once at the first time control passes through their declaration. For this case, y is initialized after main() is invoked, and x has been initialized with value 5, then y is initialized as 5 too.

are initialized the first time control passes through their declaration

In C, static variables are initialized prior to program startup, i.e. before main() is invoked; y can't be initialized from local variable x in main().

Its lifetime is the entire execution of the program and its stored value is initialized only once, prior to program startup.

My guess would be that this is a different compiler interpretation of https://en.cppreference.com/w/cpp/language/storage_duration#Static_local_variables

Usually, you can only assign static values to static variables. This includes the .data section of your executable (e.g. all char*/c-style strings are static by nature).

Since x is not a static value, gcc complains rightfully so. G++ is the c++-compiler and therefore has a different implementation to gcc, which is C by default.

Related