非const指针转const指针后转回原类型是否存在未定义行为?
这段代码不存在未定义行为,原因如下
好问题!咱们先把C++标准里关于const_cast和未定义行为的核心规则拎出来:未定义行为只发生在你用const_cast修改一个本身是const的对象的时候——重点是对象本身的const属性,而不是你中间转了多少次指针的const类型。
咱们逐行拆解你的代码:
- 原始对象
int i = 0;是非const的,这是整个场景的关键前提。 int * pi = &i;:普通指针指向非const对象,完全合法。const int * const_pi = const_cast<const int*>(pi);:把普通指针转成const指针,这只是给指针加上了“只读”的类型限制,但指向的对象还是那个非const的i,没有任何问题。int * non_const_pi = const_cast<int*>(const_pi);:把const指针转回普通指针,因为指向的对象本身是非const的,这个转换完全符合C++标准,不存在风险。- 后续的
*non_const_pi = 0;、*non_const_pi = 1;以及int j = *non_const_pi;:都是在修改/读取原本的非const对象i,完全合法,没有任何未定义行为。
针对你担心的第二个问题:编译器不会假设non_const_pi是从const指针转换而来,从而跳过修改操作。编译器的优化逻辑是基于对象的实际const属性:只要对象本身不是const,编译器就不能假设它不会被修改(毕竟可能还有其他指针指向它,比如代码里的pi)。哪怕你通过const_cast转了一圈,编译器也没法跳过对非const对象的修改操作——否则会破坏程序的正确性,这是编译器绝对不会做的。
补充一个反例帮你理解UB的场景:如果你的原始对象是const int i = 0;,那哪怕你用const_cast转成普通指针去修改i,这时候才会触发未定义行为——因为对象本身是const的,C++标准明确禁止修改这类对象。
内容的提问来源于stack exchange,提问作者Tuff Contender
相关产品推荐
相关产品推荐

