Search code examples
c++visual-c++constexprstatic-variablesstatic-initialization

Constexpr constructor for a static variable results in dynamic initialization


I have the following program:

#include <iostream>

void Init();

struct Foo {
    Foo() {
        int *p = new int; // just to make sure Foo's ctor is not a constant expression
        Init();
    }
} foo;

struct Bar {
    constexpr Bar()
        : value(0) { }
    int value;
} bar;

void Init() {
    bar.value = 1;
}

int main()
{
    std::cout << bar.value << std::endl;
}

Here foo's constructor is not a constant expression, so we'll have dynamic initialization of foo. But bar's constructor seems to be a constant expression, so we'll have static initialization of bar. So, bar's ctor must be called before foo's one and we'll see 1 as output. And I observe such result for GCC 8.3.0 and Clang 8.0.0. But for Visual C++ actual output is 0 and when I debug the application, I see that foo's dynamic initialization is made first and then bar's dynamic initialization is made.

Is the behavior that I observe (bar.value == 0) valid according to C++ 17 standard?

I'm using C++ compiler version 19.16.27027.1 for x86 Debug build or Release build with ctor's marked with __declspec(noinline).


Solution

  • Probably I am late to the party, but this is a compiler bug, which also affects some portions of Boost,see https://developercommunity.visualstudio.com/t/class-with-constexpr-constructor-not-using-static/336946

    This bug was fixed in: visual studio 2019 version 16.5 (March, 2020).

    BTW, C++20 introduces the keyword constinit to assert that a variable has static initialization.