紧接出作用域变量的新变量,能否保证偏移一字取到原变量值?
该C++代码的输出结果是否始终能得到保证?
示例代码
int main() { {int x = 532;} int xc; int x = *(&xc+1); cout << x << endl; // prints 532 }
问题描述
在上述C++代码中,先在内部作用域定义int变量x并赋值532,该变量随即出作用域;紧接着定义int变量xc,随后通过*(&xc+1)获取值并赋给新的int变量x,打印结果为532。请问该结果是否始终能得到保证?原因是什么?
回答
结果不能得到保证,核心原因是这段代码存在未定义行为,具体如下:
- 内部作用域的变量
x销毁后,其内存只是被标记为可复用,但C++标准没有强制要求后续变量xc必须紧邻它分配。编译器完全可以给xc分配其他内存地址,此时&xc+1指向的就不是原来x的内存区域,读取的值毫无意义。 *(&xc+1)属于典型的未定义行为:&xc指向xc,&xc+1指向xc之后的一个int大小的内存位置,但这个位置并没有被当前作用域的合法变量占用。根据C++标准,访问这类未被合法分配的内存,编译器可以做任何处理——可能输出532,可能输出随机垃圾值,甚至直接导致程序崩溃。- 编译优化、编译器实现都会影响结果。比如开启高等级优化时,编译器可能直接删掉内部作用域的
x(因为它没有被后续代码合法引用),对应的内存区域早被其他数据覆盖,此时读取的结果必然不是532。
内容的提问来源于stack exchange,提问作者Andrew Salinas
相关产品推荐
相关产品推荐

