库中跨文件全局变量初始化的安全性疑问及规则分析
全局变量初始化安全疑问
我正在处理一个项目,库中有如下近似代码:
// a.cpp static bool map_exists; int GetMappedValue(int value) { if (!map_exists) { map_exists = true; // 用于初始化SomeMap的各类代码 } return SomeMap.Get(value); };
/// b.cpp const int mapped_value = GetMappedValue(3);
和安全性已被充分验证的Meyer单例不同,我不确定这段写法是否安全。核心担忧是:map_exists可能无法保证在mapped_value初始化时已完成初始化。
根据C++初始化规则:因为GetMappedValue未标记为constexpr,常量初始化不适用,所以mapped_value不会被静态初始化,仅会被零初始化;而map_exists则被保证会被静态初始化(零初始化为false)。
但这里存在提前动态初始化的潜在问题:如果编译器决定对mapped_value执行提前动态初始化,目前无法保证它的初始化顺序晚于map_exists。
关于提前动态初始化,规则要求同时满足以下两个条件,编译器才允许将动态初始化的变量转为静态初始化(本质是编译时完成):
- 该初始化的动态版本不会在初始化前修改任何命名空间作用域的其他对象的值
- 该初始化的静态版本产生的变量值,与所有非必须静态初始化的变量均被动态初始化时的结果相同
第一个条件是否被违反?mapped_value的动态初始化确实会修改map_exists,但map_exists被保证在此之前已完成静态初始化,所以第一个条件似乎不违反。不过我不确定第二个条件是否满足。
内容的提问来源于stack exchange,提问作者pk1234d
相关产品推荐
相关产品推荐

