小编Lot*_*ney的帖子

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

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

无序动态初始化,其[原文如此]仅适用于(静态/线程局部)类模板静态数据成员和可变模板(因为C ++ 14)未明确专业。

因此,静态模板似乎更容易受到“静态初始化顺序惨败”(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";
}
Run Code Online (Sandbox Code Playgroud)

顺便说一句,如果有人是专家对这个我有一个相关的,悬而未决的问题(这将是容易对这样的专家来回答)这里。此外,如果我对其他问题的回答是否定的(即constexpr对所有翻译单位都无济于事),这里的含义是什么?

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

同样,我认为没有理由假定编译器中的常量初始化器不需要动态初始化器就可以初始化。在标准中没有警告说没有恒定的初始化是不够的。

我意识到有些人可能认为这是个过分关注的问题,但是我正在开发对安全至关重要的软件,并且在解决此问题之前,我公司已暂停采用C ++ 14。

c++ initialization global-variables language-lawyer constexpr

6
推荐指数
1
解决办法
233
查看次数

constexpr变量是否需要“静态初始化顺序失败”?

如果我初始化constexpr变量foo在一个翻译单元,其具有非缺省值,然后一个初始化另一个constexpr变量barfoo在另一翻译单元有可能是bar之前被初始化foo导致bar,是由初始化为零或缺省初始化foo。即与在非constexpr情况下(静态初始化顺序彻底失败有效)不同,编译器和链接器是否将分析依赖性顺序以确保正确的结果?

另外,constexpr变量模板如何受到影响?在单个翻译单元中,它们的初始化顺序是不确定的。

首选C ++ 17标准答案。

更新:这是一个最小的示例。有用; 那就是问题所在。至此,我99%确信这可以通过静态初始化命令惨败(TSIOF)来解决。但是,由于该问题的极端,阴险性质,我需要确认这是可以的。我相信该代码不会受到TSIOF的困扰,因为在xh命令abx.cc转换单元中包含了yh 。但是,AFAIU有2个翻译单元:一个包含a,另一个包含b。此外,AFAI-sort-of-U对a错误的多重定义不会出现,因为static关键字具有内部链接,a仍然具有全局范围

编译为:

clang++ -std=c++17 x.cc y.cc  #or g++
Run Code Online (Sandbox Code Playgroud)

可能的输出:

in foo
Run Code Online (Sandbox Code Playgroud)

可能的输出:

assertion failed (core dumped)
Run Code Online (Sandbox Code Playgroud)

文件x.cc:

#include "x.h"
int main(){ assert(b == 42); foo(); }
Run Code Online (Sandbox Code Playgroud)

文件xh:

#pragma once
#include "y.h"
static constexpr int b = a+1;
Run Code Online (Sandbox Code Playgroud)

文件y.cc:

#include …
Run Code Online (Sandbox Code Playgroud)

c++ initialization global-variables constexpr

5
推荐指数
1
解决办法
414
查看次数