用于静态变量的Constexpr构造函数会导致动态初始化

und*_*ind 0 c++ static-variables visual-c++ static-initialization constexpr

我有以下程序:

#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;
}
Run Code Online (Sandbox Code Playgroud)

这里foo的构造函数不是常量表达式,因此我们将动态初始化foo。但是bar的构造函数似乎是一个常量表达式,因此我们将对进行静态初始化bar。因此,bar必须先调用的ctor,然后foo将其1视为输出。我在GCC 8.3.0和Clang 8.0.0中观察到了这样的结果。但是对于Visual C ++,实际的输出是,0并且在调试应用程序时,我看到foo先进行bar的动态初始化,然后进行动态的初始化。

bar.value == 0根据C ++ 17标准,我观察到的行为()是否有效?

我正在使用x ++ Debug build或Release build的C ++编译器版本19.16.27027.1,其ctor标记为__declspec(noinline)

R S*_*ahu 5

但是bar的构造函数似乎是一个常量表达式,因此我们将对进行静态初始化bar

那是不正确的理解。

constexpr构造可用于构建一个非const对象太。发生这种情况时,将使用动态初始化来初始化该对象。就您而言,bar是一个非const对象。因此,使用动态初始化将其初始化是有意义的。

将代码更改为:

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

constexpr Bar bar;
Run Code Online (Sandbox Code Playgroud)

应该将的初始化更改bar为静态初始化。

但是,如果bar更改为const对象,则将无法使用

bar.value = 1; 
Run Code Online (Sandbox Code Playgroud)

在中Init()。我只想指出如何进行更改,bar以便可以在静态初始化期间将其初始化。