MSVC 2017 Community с -std=c++17
дросселями на следующем примере:
#include <iostream>
struct TC
{
static TC const values[];
static TC const& A;
static TC const& B;
static TC const& C;
int const _value;
};
inline constexpr TC const TC::values[]{ { 42 }, { 43 }, { 44 } };
inline constexpr TC const& TC::A{ values[0U] };
inline constexpr TC const& TC::B{ values[1U] };
inline constexpr TC const& TC::C{ values[2U] };
int main(int, char**) noexcept
{
std::cout << std::boolalpha
<< "&A == &values[0]? " << (&TC::A == &TC::values[0U]) << "\n"
<< "&B == &values[1]? " << (&TC::B == &TC::values[1U]) << "\n"
<< "&C == &values[2]? " << (&TC::C == &TC::values[2U]) << "\n";
return 0;
}
Выход ожидаемый :
&A == &values[0]? true
&B == &values[1]? true
&C == &values[2]? true
Что такое оба gccи clang производят, но MSVC выдает:
&A == &values[0]? true
&B == &values[1]? false
&C == &values[2]? false
MSVC дает правильные результаты, если элемент _value
удален и пользовательский конструктор отсутствует.
Как все этонаходится в пределах одной единицы перевода, я понимаю, что это подпадает под Частично упорядоченная динамическая инициализация :
2) Частично упорядоченная динамическая инициализация, котораяприменяется ко всем встроенным переменным, которые не являются явно или явно конкретизированной специализацией.Если частично упорядоченный V определен перед упорядоченным или частично упорядоченным W в каждой единице перевода, инициализация V выполняется до инициализации W (или происходит раньше, если программа запускает поток)
Я не могу использовать функцию для обеспечения порядка инициализации, так как мне требуются constexpr
значения и constexpr
ссылки на них.
Так что вопрос в том, MSVC это в нарушение стандарта * здесь, верно?
* Конечно cppreference.com не является "стандартом", но я предполагаю, что информация там правильно получена.