c++ - 全局常量对静态数据成员的初始化是否会导致未定义的行为?
问题描述
我遇到了这个 TC 的惊人答案(编辑:我现在认为这是错误的)并且有一个后续问题。请考虑一个代码,其中我使用在全局命名空间范围内声明的整数类型的不断初始化的常量变量来不断初始化常量静态数据成员或声明我的类的数组数据成员。更好的说明示例:
const int internal_linkage_constant = 1;
class ExternalLinkageClass
{
static const int constexpr_value = internal_linkage_constant; // #1
int arr[internal_linkage_constant]; // #2
};
所有这些类的定义都在头文件中,并且可能在多个翻译单元之间共享。全局常量必须在这些定义之前定义,并且本质上不能有外部链接才能在常量表达式中使用。现在我的问题是:这样的初始化是否会由于违反 ODR 而导致未定义的行为?
解决方案
没有例外。C++98 标准在第 3.2 章中指出:
如果每个定义出现在不同的翻译单元中,并且定义满足以下要求,则程序中可以有多个类类型的定义(...):
- D 的每个定义都应由相同的记号序列组成;和
- 在 D 的每个定义中,根据 3.4 查找的对应名称应指在 D 的定义中定义的实体,或应指同一实体,在重载决议 (13.3) 和部分模板特化 (14.8) 匹配之后.3),除了如果对象在 D 的所有定义中具有相同的整数或枚举类型,并且该对象使用常量表达式 (5.19) 初始化,则名称可以引用具有内部链接或没有链接的 const 对象,并且使用对象的值(但不是地址),并且该对象在 D 的所有定义中具有相同的值;
- (……)
推荐阅读
- xcode10 - 使用 xcodebuild 10 beta 运行 xcodebuild 测试时,如何解决“意外的重复创建者”?
- aspose - 使用 Aspose.Words 进行转换时如何在 HTML 中包含 PageFields
- tfs - TFS 2018 WebLayout 扩展强制所有贡献从扩展显示
- javascript - 从 console.log 中删除多余的对象
- python - 为什么python模块名称有一些大写字母但总是以小写形式导入?
- javascript - 正则表达式匹配多个可能的选项
- ios - 内循环;构建可能会产生不可靠的结果:Xcode 错误
- java - JavaFX ListView 基本应用
- javascript - 如何从控制器{angularJS} 到脚本{js} 获取值
- javascript - API 失败时 Ember.js 模型的默认值