Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

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?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

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
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading