C++静态局部变量程序启动期初始化相关技术疑问
关于静态局部变量零/常量初始化的问题解答
首先明确cppreference的描述:
在块作用域中用static或thread_local(C11起)说明符声明的变量拥有静态或线程(C11起)存储期,但会在控制首次经过其声明时进行初始化(除非其初始化是零初始化或常量初始化,这种情况可在首次进入该块前执行)。
针对「除非」部分的三个问题解答如下:
1. 零初始化和常量初始化的代码示例
零初始化示例
零初始化针对静态存储期变量,会在程序启动阶段将变量内存置零(基本类型初始化为0/0.0等,平凡类成员全部置零):
void calculate() { // 静态局部int未显式初始化,触发零初始化,值为0,在main()前完成 static int counter; counter++; }
常量初始化示例
常量初始化要求初始化表达式是常量表达式,会在编译阶段或程序启动早期完成:
void print_config() { // 用常量表达式初始化静态局部const变量,触发常量初始化 static const int DEFAULT_PORT = 8080; // constexpr变量本身属于常量初始化范畴 static constexpr double DEFAULT_RATE = 0.75; printf("Port: %d, Rate: %.2f\n", DEFAULT_PORT, DEFAULT_RATE); }
2. 类对象是否可以被零初始化或常量初始化?
可以,但需要满足对应条件:
- 零初始化:当类是平凡类型(无用户定义构造函数、无虚函数、无非平凡成员等)时,静态局部类对象会被零初始化,所有成员都会被置零:
struct Config { int timeout; bool enable_log; }; void init_service() { // 平凡类的静态局部对象,触发零初始化:timeout=0,enable_log=false static Config service_config; } - 常量初始化:当类拥有
constexpr构造函数,且初始化参数是常量表达式时,静态局部类对象可以触发常量初始化:struct Point { int x, y; // constexpr构造函数,满足常量表达式要求 constexpr Point(int a, int b) : x(a), y(b) {} }; void draw() { // 用常量表达式初始化,触发常量初始化 static constexpr Point origin(0, 0); }
3. 类对象满足条件时,构造函数是否在main()前调用?
分两种情况:
- 对于零初始化的平凡类对象:不需要调用构造函数,直接对内存进行零填充,这个操作在main()启动前完成。
- 对于常量初始化的类对象:如果使用的是
constexpr构造函数,构造过程会在编译阶段或程序启动早期(main()前)完成,相当于直接把构造后的对象值写入内存,不会等到首次进入块作用域才执行构造。
内容的提问来源于stack exchange,提问作者NPS
相关产品推荐
相关产品推荐

