为什么静态初始化顺序仍未指定
Why is static initialization order STILL unspecified?
>编译器是否拥有生成所有全局变量的依赖树并为它们创建定义良好且正确的初始化顺序所需的所有信息?我意识到你可以用全局变量编写一个循环依赖关系 - 只使这种情况未定义的行为 - 编译器可以警告并可能出错。
通常,这种事情的原因是编译器制作者会很负担或导致编译速度显着变慢。我没有指标或证据表明这两种情况在这种情况下都不是真的,但我的倾向是两者都不是真的。
嗯,想象一下以下设置,它C++完全有效,但分析起来很棘手:
// TU #1
bool c = coin();
// TU #2
extern bool c;
extern int b;
int a = c ? b : 10;
// TU #3
extern bool c;
extern int a;
int b = c ? 20 : a;
很明显,TU #1 需要先初始化,但然后呢?具有引用到静态的标准解决方案允许您使用标准C++正确编写此代码,但通过修复全局初始化顺序来解决此问题似乎很棘手。
编译器可以处理的部分实际上是定义的:具有静态存储持续时间的对象按照其定义在翻译单元中出现的顺序构造。销毁顺序正好相反。
在翻译单元之间对对象进行排序时,通常不会显式表示对象的依赖关系组。但是,即使显式重新配置了依赖项,它们实际上也没有多大帮助:在小型项目中,具有静态存储持续时间的对象之间的依赖项可以相对容易地管理。事情变得有趣的地方是大型对象,但这些对象更有可能包含表单的初始化
static T global = functionWhichMayuseTheword();
也就是说,在排序有用的情况下,它注定不起作用。
有一种微不足道的方法可以确保对象及时构造,这在C++中甚至是线程安全的(它在 C++03 中不是线程安全的,因为该标准首先没有提到任何线程的概念):使用函数本地static
对象并返回对它的引用。这些对象将根据需求构建,但如果它们之间存在依赖关系,这通常是可以接受的:
static T& global() {
static rc = someInitialization();
return rc;
}
鉴于有一个简单的解决方法,既没有提案也没有证明提案有效的工作实现,因此更改全局对象初始化方式的状态几乎没有兴趣。更不用说改进对全局对象的支持似乎与使goto
变得更好一样有用。
我不是编译器作者,所以对我说的话持保留态度。我认为原因如下。
1)希望保留单独编译的C模型。链接时间分析当然是允许的,但我怀疑他们不想让它成为必需的。
2)Meyers Singleton(特别是现在它已经变得线程安全)提供了一个足够好的替代方案,因为它几乎和全局变量一样易于使用,但提供了您正在寻找的保证。
- 从 XML 中读取未指定结构的每个数据成员
- 用数据填充未指定大小的数组
- 未按顺序出现在数组中的小写字母
- 访问从联合与另一个成员集复制的联合中的一个成员是否未定义或未指定?
- 双循环变量的相等条件:未指定还是未定义
- SQL Server-未找到数据源名称,也未指定默认驱动程序
- 无法创建长度未指定
- 在Visual Studio中更新Qt翻译(.ts文件)时出现未指定错误
- 是否未指定在未评估的上下文中实例化模板/lambda
- 未定义与未指定与实现定义的行为
- 在 c++ 中获取未指定数量的输入
- 摆动,传递未指定维度的阵列
- 在尝试提交作业警告时,我一直在警告:与未指定行为的字符串字面结果比较[-WADDRESS]
- 我的基本C 程序中有一个未指定的错误
- OPENCV错误:未指定的错误(未实现该函数)
- 函数参数中数组大小未指定
- 从源代码编译 openCV:*** 未指定目标,也未找到生成文件.停
- 字符串运算符的求值顺序未指定
- 为什么在 c++ 中未指定函数参数的计算顺序
- 为什么静态初始化顺序仍未指定