constexpr(即常量初始化)模板变量的初始化顺序是否有保证?

2024-02-01

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,直到此问题得到解决。


基于基本.启动.静态 https://timsong-cpp.github.io/cppwp/basic.start.static:

常量初始化如果变量或临时变量被执行 对象与static或线程存储持续时间由初始化 实体的常量初始值设定项。

在你的代码中:

template<class T> static constexpr T a = 41; // constant initialization

是在做常量初始化这使得:

template<class T> static constexpr T b = a<T>+1;

初始化为42由于模板的不断的评估.

其中指出(从表达式.const/8.7 https://timsong-cpp.github.io/cppwp/expr.const#8.7):

名称显示为潜在常量的变量 表达式可以是常量表达式变量或者是非易失性的 const 限定的整型或引用类型。

因此,保证输出始终"success"ful.

NOTE From basic.start.static/2 https://timsong-cpp.github.io/cppwp/basic.start.static#2:

一起,零初始化 and 常量初始化叫做静态初始化

-- not动态初始化

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

constexpr(即常量初始化)模板变量的初始化顺序是否有保证? 的相关文章

随机推荐