From en.cppreference.com/w/cpp/language/initialization http://en.cppreference.com/w/cpp/language/initialization:
无序动态初始化,[sic]仅适用于未显式专门化的(静态/线程本地)类模板静态数据成员和变量模板 (C++14 起)。
因此,静态模板似乎很容易受到更糟糕版本的影响静态初始化顺序惨败 (TSIOF) https://isocpp.org/wiki/faq/ctors#static-init-order(即翻译单元内无序)。
使用 constexpr 是否可以消除此漏洞?
即以下代码的输出保证 to be 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";
}
顺便说一句,如果有人是这方面的专家,我有一个相关的、未回答的问题(这样的专家很容易回答)here https://stackoverflow.com/questions/50381258/is-the-static-initialization-order-fiasco-a-concern-for-constexpr-variables。
此外,如果答案为我的另一个问题 https://stackoverflow.com/questions/50381258/is-the-static-initialization-order-fiasco-a-concern-for-constexpr-variables是负数(即 constexpr 对跨翻译单元没有帮助)?
更新:我需要澄清我的担忧是什么。原始问题标题询问初始化顺序是否是 constexpr 模板变量的一个问题。我已经澄清了。我不关心示例中是否发生动态初始化;事实并非如此。我担心的是,既然在动态初始化情况下不能假设有序初始化,那么在常量初始化情况下可以假设吗?在看到动态初始化模板变量(在同一翻译单元内)的行为之前,我从来没有想到过这一点。然而,由于动态初始化、静态持续时间模板变量不提供有序初始化,我现在认为没有理由假设常量初始化、静态持续时间模板变量也保证了有序初始化。我需要 100% 确定模板变量的常量初始化按照它们在 TU 中的定义顺序进行。
同样,如果动态初始化器不需要的话,我认为没有理由假设编译器内的常量初始化器需要按顺序初始化。标准中没有警告常量初始化是无序的还不够。
我意识到有些人可能认为这是过度关注,但我正在开发安全关键型软件,并且我的公司已暂停采用 C++14,直到此问题得到解决。