仅针对未明确特化的(静态/线程本地)类模板静态数据成员和变量模板(自 C++14 起),无序动态初始化。因此,静态模板似乎容易受到更糟糕的 The Static Initialization Order Fiasco (TSIOF)(静态初始化顺序混乱) 的影响(即在一个翻译单元内无序)。
使用 constexpr 可以消除这种漏洞吗?
即下面代码的输出是否保证是
success
?显然,由于这个问题的性质,工作示例不足以作为答案;必须引用标准中的语句。(优先考虑 C++17 的答案)
#include<cassert>
template<class T> static constexpr T a = 41;
template<class T> static constexpr T b = a<T>+1;
int main(){
assert(b<int> == 42);
std::cout <<"success\n";
}
顺便提一下,如果有专家在这方面,请回答我相关的未解决问题(对于这样的专家来说,这应该很容易回答)这里。 另外,如果我的其他问题的答案是否定的(即constexpr不能跨翻译单元帮助),会有什么影响?
更新:我需要澄清这里的关注点。原始问题标题问是否初始化顺序对constexpr模板变量具有影响。我已经澄清了。我不担心示例中是否发生动态初始化;它没有。我的担忧是,在动态初始化情况下无法假定有序初始化,那么在常量初始化情况下可以吗?在看到相同翻译单元内的动态初始化模板变量的行为之前,我甚至从未想过这个问题。然而,由于静态持续时间的动态初始化模板变量并不提供有序初始化,因此我现在认为也没有理由假设具有保证顺序初始化的静态持续时间的常量初始化模板变量。我需要百分之百确定模板变量的常量初始化在翻译单元内按照其定义的顺序进行。
再次强调,如果动态初始化程序没有按顺序初始化,我认为无法假定编译器内部的常量初始化程序需要按顺序初始化。标准中没有警告说明常量初始化是无序的不足以说明问题。
我意识到某些人可能认为这是过度关注,但我正在开发安全关键的软件,而我的公司已经将采用C++14暂停,直到解决此问题。
static_assert
来更改你的assert
。 - Jarod42