使用-std=c++17
的MSVC 2017 Community对以下示例代码支持不佳:
#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
如果删除
_value
成员并且没有用户定义的构造函数,MSVC会给出正确的结果。由于所有这些都在单个翻译单元中,我的理解是这属于部分有序动态初始化:
我不能使用函数来确保初始化顺序,因为我需要2) 部分有序动态初始化适用于所有不是隐式或显式实例化特化的内联变量。如果在每个翻译单元中,部分有序的V在有序或部分有序的W之前被定义,则V的初始化在W的初始化之前(或在程序启动线程时发生)。
constexpr
值和constexpr
对它们的引用。所以问题是,MSVC在这里违反了标准*,对吗?
*当然cppreference.com不是“标准”,但我假设那里的信息是正确的。
constexpr
specifier shall be applied only to the definition of a variable...'" Soconstexpr
(apparently) is not needed on the declaration. - monkey0506