C++聚合初始化是编译期还是运行时生效?无constexpr能否实现全局对象编译期初始化
解答
可以通过聚合初始化实现你要的全局对象编译期静态初始化效果,不需要constexpr支持,完全兼容旧版本C++标准。
前提条件
你的MyObj类型需要符合旧版C++的聚合类型要求:
- 不存在任何用户自定义的构造函数
- 所有非静态成员均为公有访问权限
- 无基类、无虚函数
- C++11之前的标准还要求不存在默认成员初始化器
实现原理
满足上述条件的聚合类型,使用编译期常量作为初始化器进行聚合初始化时,全局对象会被编译器直接放入已初始化数据段,生成的二进制文件中就会包含你设置的初始值,不需要在程序启动阶段执行构造逻辑,完全符合你要的效果。
你之前使用自定义构造函数的写法属于全局对象的动态初始化,初始化逻辑会在程序启动时执行,因此二进制文件中该对象的存储区默认是全0的BSS段,和聚合初始化的静态初始化有本质区别。
Windows平台适配说明
你提到的__declspec(dllexport)、extern "C"修饰符仅影响对象的符号导出规则,和初始化逻辑无关,不会干扰聚合初始化的静态初始化效果,示例代码如下:
// 聚合类型定义,删除自定义构造函数,成员全公有 struct MyObj { const char* name; int type; float score; }; // 带导出修饰符的全局聚合初始化 extern "C" __declspec(dllexport) MyObj obj = { "object1", 3, 7.2F };
注意事项
- 聚合初始化的参数顺序必须和类成员的声明顺序完全一致,避免出现初始化错位的问题
- 初始化列表中的所有值必须是编译期可确定的常量(字符串字面量、数值常量等),如果使用运行期才能计算的值作为初始值,依然会触发动态初始化
内容的提问来源于stack exchange,提问作者David
相关产品推荐
相关产品推荐

