Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Initialization order of static constexpr data members

In a code like this:

#include <iostream>

template<int I>
struct A {
    static constexpr int I1 = I + 1;
    static constexpr int I2 = I1 + 1;
};

int main() {
    std::cout << A<1>::I1 << " " << A<1>::I2 << std::endl;
}

is it safe to assume that I2 will get initialized correctly, i.e. that I1 gets initialized before I2?

like image 847
tmlen Avatar asked Oct 15 '25 09:10

tmlen


1 Answers

Initialization order isn't really meaningful for anything that's constexpr. A constexpr variable must be initialized by a constant expression, and since constant expressions don't have any side effects, and mutable global state isn't something that exists at compile time, you don't have to worry about initialization order.

If you want to get into the specifics:

Constant initialization is performed if a variable or temporary object with static or thread storage duration is constant-initialized ([expr.const]). [...] Together, zero-initialization and constant initialization are called static initialization; all other initialization is dynamic initialization. All static initialization strongly happens before ([intro.races]) any dynamic initialization.

- https://eel.is/c++draft/basic.start.static#2

Initialization order for static initialization doesn't matter, because everything is being initialized to a compile-time constant. It's only an issue for dynamic initialization.

For constant initialization, the only thing that matters is the order of definition:

static constexpr int I1 = I + 1;  // I1 defined before I2
static constexpr int I2 = I1 + 1; // I2 can use this definition

Any constexpr variable, including static constexpr data members must be initialized where they are defined. Any constant expressions that appear further down in code then inevitably have that definition available, because the program is compiled from top to bottom. In this example, it means that:

  • I1 must always be defined right where it's declared because it's constexpr
  • I2 always has this definition available, because it appears further down in the code
like image 122
Jan Schultke Avatar answered Oct 17 '25 21:10

Jan Schultke



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!