У меня есть следующая программа:
#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;
}
Здесь конструктор 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?
Я использую компилятор C ++ версии 19.16.27027.1 для x86. Отладочная сборка или сборка выпуска с ctor, помеченными __declspec(noinline)
.