带const引用参数的函数能否修改非const底层对象?是否触发未定义行为?
问题解答
核心结论
func可以通过const_cast修改a,且不会触发未定义行为,修改后std::cout会输出不等于5的结果。
具体解释
C++标准的规则边界
只有当你试图修改本身就是const类型的对象时,使用const_cast去掉const属性才会导致未定义行为。如果原始对象是非const的(比如例子里的a),哪怕它是通过const int&的形式传递到函数中,用const_cast<int&>(arg)将其转换为非const引用后修改底层对象,完全符合标准要求,是合法操作。对应代码的行为
main中的a是普通非const int,传递给func的const int& arg只是对a的只读引用。在func内部执行如下代码是合法的:
void func(const int& arg) { int& mutable_arg = const_cast<int&>(arg); mutable_arg = 10; // 修改的是原始的非const对象a,合法 }
此时main中std::cout << a会输出10。
- 对编译器优化的影响
确实如你所说,当func的定义在另一个编译单元时,编译器仅通过void func(const int& arg)的声明无法确定func是否会修改a——因为标准允许这种合法的const_cast操作。因此编译器不能假设a的值在调用func后保持不变,必须重新从内存中读取a的最新值,这会限制一些寄存器缓存类的优化。
内容的提问来源于stack exchange,提问作者Franz Ferdinand
相关产品推荐
相关产品推荐

