常量初始化自引用为何合法?C++标准相关规则探究
全局std::string自引用初始化的C++规则解析
先看你提到的第一段代码:
#include <string> const std::string MY_STR{MY_STR + " hello"};
这段代码能在主流编译器编译通过,但本质是未定义行为。C++标准允许在静态存储期对象(比如全局变量)的初始化器中引用该对象本身,但此时对象还未完成构造——也就是说,MY_STR在初始化时自身还处于未初始化状态,用它做字符串拼接,实际是在操作一块未初始化的内存,运行结果完全不可预测。
再看第二段代码:
#include <string> const std::string MY_STR{MY_STR.c_str()};
它同样能编译通过,原因和第一段类似:语法上MY_STR已经被声明,调用其成员函数c_str()属于合法语法,编译器不会报错。但此时MY_STR的生命周期还没开始(构造函数未执行完毕),调用非静态成员函数访问未初始化的对象内存,属于标准定义的未定义行为——程序可能崩溃、返回垃圾指针,或者出现其他异常表现。
相关C++标准规则
- 根据C++标准[basic.life]章节:对象的生命周期从构造完成时开始(类类型对象即构造函数执行完毕)。在生命周期开始前,除了用于初始化对象本身的特定操作外,访问对象的非静态成员、使用对象的值都是未定义行为。
- [expr.prim.id.unqual]章节明确:引用正在初始化的静态存储期对象是合法语法,但对象此时处于未初始化状态,后续操作的行为属于未定义范畴。
简单来说:这两段代码不是语法错误,所以编译器允许编译,但运行行为完全不可控,标准不保证任何结果。
内容的提问来源于stack exchange,提问作者mascoj
相关产品推荐
相关产品推荐

