"static initialization order fiasco"是 constexpr 变量的问题吗?
Is the "static initialization order fiasco" a concern for constexpr variables?
如果我在一个翻译单元中用非默认值初始化一个constexpr
变量foo
,然后在另一个翻译单元中用foo
初始化另一个constexpr
变量bar
,是否可以在foo
之前初始化bar
,从而导致由零或默认初始化foo
初始化的bar
。 即与非 constexpr 情况(静态初始化顺序惨败生效)不同,将编译器和链接器分析依赖关系排序以保证正确的结果?
此外,constexpr 变量模板会受到怎样的影响?它们的初始化顺序在单个翻译单元中未定义。
C++17个标准答案优先。
更新:下面是一个最小的例子。它有效;这就是问题所在。在这一点上,我 99% 确定这是安全的,不会受到静态初始化顺序惨败 (TSIOF)的影响。但是,由于该问题的极端,阴险性质,我需要确认这是可以的。我相信这段代码不会受到 TSIOF 的影响,因为 y.h 包含在 x.h 订单中,a
和b
在 x.cc 翻译单元中。但是,AFAIU有2个翻译单元:一个包含a,另一个包含b。此外,AFAI-sort-of-U 不会产生a
错误的多重定义,因为静态关键字赋予了内部链接,但a
仍然具有全局范围。
编译方式:
clang++ -std=c++17 x.cc y.cc #or g++
可能的输出:
in foo
可能的输出:
assertion failed (core dumped)
文件 x.cc:
#include "x.h"
int main(){ assert(b == 42); foo(); }
文件 x.h:
#pragma once
#include "y.h"
static constexpr int b = a+1;
文件 y.cc:
#include "y.h"
#include <iostream>
void foo(){
std::cout << " in foo n";
}
文件 Y.H:
#pragma once
static constexpr int a=41;
void foo();
这个程序保证输出in foo
吗?
由于这个问题无法通过示例来回答,因此确实需要语言律师提供相关的标准报价
这个问题是关于跨翻译单元的 STIOF。关于模板变量翻译单元中 STIOF 的一个相关的、未回答的问题在这里
在您的示例中,不存在可能的问题,因为 y.cc 中的a
与 x.cc 中的a
变量不同。因此,没有发生交叉翻译单元链接。
事实上,constexpr 变量之间不可能有交叉翻译单元链接。constexpr
的全部意义在于该值是在编译时计算的。
换句话说,constexpr 必须在我们仍在隔离编译翻译单元时解析为一个值。
因此,静态初始化顺序惨败隐式不适用于constexpr
变量,并且标准无需提及在这种情况下该怎么做。
编辑:根据要求,该标准的相关部分是10.1.5(9)[dcl.constexpr]
在任何 constexpr 变量声明中,完整表达式 初始化应为常量表达式 (8.20)。
这导致 8.20 (1) [expr.const] 具有以下注释:
[ 注意:常量表达式可以在翻译过程中计算。
这是下一页半条款背后的理由,但本身就足以排除交叉翻译单元引用。
- 为"adjacent"变量赋值时出现问题
- C++理解计算字符变量的问题
- 在通知提升间处理条件变量时未按住锁会导致问题
- C++线程安全:如果只有一个线程可以写入非原子变量,但多个线程从中读取. 会遇到问题吗?
- 将十六进制值设置为用于填充的字符变量时出现问题
- 初学者问题:如何访问此变量?
- 关于仅正确使用二传手和变量的问题
- 为什么在分配给成员变量之前获取unique_ptr的返回是一个问题?
- 将字符数组转换为结构时出现问题. 结构的字符数组变量溢出
- 在 for 循环中更新两个变量时遇到问题C++
- 为<vtkDataArray> VTK 非结构化网格声明 vtkSmartPointer 类型的变量时出现问题
- 模板类编译问题与 typedef 变量
- 简单的问题 - 如何从单独的"结构"内的'class'访问变量?
- c++问题:给一个变量赋值后,另一个变量发生了变化
- 初学者问题:C++指针/地址 - 和变量之后不是以前?
- 关于读取有效 c++ 第 4 项(将非局部静态变量替换为局部静态变量)的问题
- 我有几个关于参考变量的问题
- 面临在 if 语句之外打印变量数据的问题 完成使用 Qt 编程
- OpenCV C++ Mat 类行和列 - 它们是成员变量(和相关问题)吗?
- 指向动态内存中结构中的变量时出现问题