是否保证constexpr(即常量初始化)模板变量的初始化顺序? [英] Is the initialization order of constexpr (i.e. constant-initialized) template variables guaranteed?

查看:121
本文介绍了是否保证constexpr(即常量初始化)模板变量的初始化顺序?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

来自 en.cppreference.com/w/cpp/language/initialization


无序动态初始化, [sic] 仅适用于(静态/线程本地)类模板静态数据成员和变量模板(自C ++ 14起)未明确专用。

Unordered dynamic initialization, which [sic] applies only to (static/thread-local) class template static data members and variable templates (since C++14) that aren't explicitly specialized.

因此,静态模板似乎容易受到 静态初始化顺序惨败(TSIOF) (即翻译单元内无序)。

Therefore static templates appear to be vulnerable to an even worse version of The Static Initialization Order Fiasco (TSIOF) (i.e. unordered within a translation unit).

使用constexpr可以消除此漏洞吗?

Does use of constexpr remove this vulnerability?

ie下面的代码保证的输出是成功

i.e. is the output of the below code guaranteed to be success?

很显然,由于这个问题的性质,实际的例子不足以作为答案。标准中的引号是必需的。
(首选C ++ 17答案)

Obviously, due to the nature of this question, working examples won't suffice as answers; quotes from the standard would be required. (C++17 answers preferred)

#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对翻译单位没有帮助)?

BTW, if someone is an expert on this I have a related, unanswered question (that would be easy for such an expert to answer) here. Further, what would be the implications here if the answer to my other question is negative (i.e. constexpr doesn't help across translation units)?

更新:我需要澄清一下关注在这里。原始问题标题询问constexpr模板变量是否需要考虑初始化顺序。我已经澄清了。我不关心示例中是否正在进行动态初始化。不是。我担心的是,由于不能在动态初始化情况下假设有序初始化,因此可以在恒定初始化情况下假设有序初始化吗?在看到动态初始化的模板变量(在同一翻译单元内)的行为之前,我什至从未想到过这一点。但是,由于动态初始化的静态持续时间模板变量不提供有序的初始化,因此我现在没有理由假设常量初始化的静态持续时间的模板变量也保证了有序的初始化。我需要100%确保模板变量的常量初始化在TU中按其定义的顺序进行。

UPDATE: I need to clarify what my concern is here. The original question title asked whether initialization order is a concern for constexpr template variables. I have clarified it. I am not concerned about whether dynamic initialization is taking place in the example; it isn't. My concern is that since ordered initialization cannot be assumed in the dynamic initialization case, can it be assumed in the constant initialization case? Prior to seeing the behavior of dynamically initialized template variables (within the same translation unit) I would have never even thought of this. However, since dynamically-initialized, static-duration template variables do not provide ordered initialization I now see no reason to assume that constant-initiliazed, static-duration template variables have guaranteed ordered initialization either. I need to be 100% sure that constant initialization of template variables takes place in the order of their definition within a TU.

同样,我认为没有理由假设常量如果没有动态初始化程序,则必须在编译器内初始化程序。在标准中缺少没有警告的初始化常量是不够的。

Again, I see no reason to assume the constant-initializer-within-the-compiler is required to intialize in order if the dynamic initializer isn't. Absence of a warning in the standard that constant initialization is unordered does not suffice.

我意识到有人可能会对此表示过多的关注,但是我正在开发对安全至关重要的软件,并且在此问题之前,我公司已暂停采用C ++ 14

I realize that some may think this is excessive concern but I am working on safety-critical software and my company has placed adoption of C++14 on hold until this issue is resolved.

推荐答案

基于 basic.start.static


恒定初始化如果实体的 static 变量或临时
对象或线程存储持续时间由实体的
常量初始化程序初始化,则执行/ em>。

Constant initialization is performed if a variable or temporary object with static or thread storage duration is initialized by a constant initializer for the entity.

在您的代码中:

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

正在执行常量初始化,它使得:

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

由于模板而用 42 初始化'恒定评估

be initialized with 42 due to the templates' constant evaluation.

其中指出(来自 expr.const / 8.7 ):


其名称为变量的变量
表达式可能是常量,可能是 constexpr变量,或者是非易失性
const限定整数类型或引用类型。

a variable whose name appears as a potentially constant evaluated expression that is either a constexpr variable or is of non-volatile const-qualified integral type or of reference type.

因此,可以保证输出总是成功 ful。

Thus, it is guaranteed the output is always "success"ful.

注意来自 basic.start.static / 2


一起,零初始化恒定初始化称为
静态初始化

- not 动态初始化

这篇关于是否保证constexpr(即常量初始化)模板变量的初始化顺序?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆