C++ 中 *const* 变量 const_cast 之后的地址
address after const_cast of a *const* variable in C++
我知道下面应该是未定义的行为
因为原始变量是const。然而,这怎么可能,
&x
和 &rx
这两个地址相同,但值
他们打印的(我没有说保留,因为它根本不可能),
不是。谢谢!
const int x=10;
int& rx = const_cast<int&>(x);
rx++;
cout << x << " and " << rx << endl;
cout << "is &x == &xr: " << (&x==&rx) << endl;
G++ 4.9 的输出是
10 and 11
is &x == &xr: 1
这显然是一种未定义的行为,因此据我所知,问题不应该是为什么会发生,而是什么原因会发生。
我不知道 GCC 如何翻译和优化代码,但我最好的猜测是在 cout
行中,x
在编译时被假定为 const 值(编译器假定为 10
).
看看生成的汇编代码可能会很有趣!
编译器(好吧,上周的 clang++ 3.7.0)确实优化了代码的 "intention",不管它的合法性:
movl $_ZSt4cout, %edi
movl , %esi
callq _ZNSolsEi
movq %rax, %rbx
movl $.L.str, %esi
movl , %edx
movq %rbx, %rdi
callq _ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_l
movl , %esi
movq %rbx, %rdi
callq _ZNSolsEi
一如既往,值得注意的是,未定义行为的行为确实涵盖了 "does what you think it will do" 以及 "doesn't do what you think it will do",这当然适用于此。
const_cast
最初是 const 的值是未定义的行为,此时您已经放弃了编译器对 "sane behaviour" 的所有权利。现在发生的是编译器作者认为正确的事情——如果这意味着该值实际上被放置在只读内存位中,那么您的代码将无法成功更新该值。但在这种情况下,它只是将 x
优化为常量 10,并且 rx
变为 11 - 因为实际上 "do" 没有 x
和 [=13] 的任何其他内容=],根据编译器标准,这是 "fine"。
我知道下面应该是未定义的行为
因为原始变量是const。然而,这怎么可能,
&x
和 &rx
这两个地址相同,但值
他们打印的(我没有说保留,因为它根本不可能),
不是。谢谢!
const int x=10;
int& rx = const_cast<int&>(x);
rx++;
cout << x << " and " << rx << endl;
cout << "is &x == &xr: " << (&x==&rx) << endl;
G++ 4.9 的输出是
10 and 11
is &x == &xr: 1
这显然是一种未定义的行为,因此据我所知,问题不应该是为什么会发生,而是什么原因会发生。
我不知道 GCC 如何翻译和优化代码,但我最好的猜测是在 cout
行中,x
在编译时被假定为 const 值(编译器假定为 10
).
看看生成的汇编代码可能会很有趣!
编译器(好吧,上周的 clang++ 3.7.0)确实优化了代码的 "intention",不管它的合法性:
movl $_ZSt4cout, %edi
movl , %esi
callq _ZNSolsEi
movq %rax, %rbx
movl $.L.str, %esi
movl , %edx
movq %rbx, %rdi
callq _ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_l
movl , %esi
movq %rbx, %rdi
callq _ZNSolsEi
一如既往,值得注意的是,未定义行为的行为确实涵盖了 "does what you think it will do" 以及 "doesn't do what you think it will do",这当然适用于此。
const_cast
最初是 const 的值是未定义的行为,此时您已经放弃了编译器对 "sane behaviour" 的所有权利。现在发生的是编译器作者认为正确的事情——如果这意味着该值实际上被放置在只读内存位中,那么您的代码将无法成功更新该值。但在这种情况下,它只是将 x
优化为常量 10,并且 rx
变为 11 - 因为实际上 "do" 没有 x
和 [=13] 的任何其他内容=],根据编译器标准,这是 "fine"。