描述你的问题
pc是一个指向i的const指针,通过const_cast我们得到了一个普通的指针p。直接输出pc,p,以及&i,输出的都是003BF800,但是输出*pc,i却有1和32两种结果,那么请问在003BF800这个地址中存放的到底是整数1还是整数32,以及为什么会出现这种现象?
贴上相关代码
#include <iostream>
using namespace std;
int main()
{
const int i = 32;
const int *pc = &i;
int *p = const_cast<int*>(pc);
*p = 1;
cout << *pc << " " << *p <<" "<<i<< endl;
cout << pc << " " << p << " " << &i << endl;
return 0;
}
贴上报错信息
贴上相关截图
已经尝试过哪些方法仍然没解决(附上相关链接)
黄舟2017-04-17 13:26:38
In 003BF800
, what is saved is indeed the integer 1, because the p
pointer has changed its value. However, why the value of i is 32 may be because i is a constant expression "constexpr
" that can be calculated at compile time, and the relevant content has been replaced at compile time.
迷茫2017-04-17 13:26:38
The new variable obtained by removing the const_cast
qualifier by const
. If the corresponding original variable is of non-constant (nonconst
) type, you can change the new variable. If the original variable was of type constant, changing the new variable is undefined behavior. The specific situation is determined by the compiler.
It is undefined behavior for the questioner to overwrite the original variable p
through the pointer i
.
PHPz2017-04-17 13:26:38
There is nothing strange about this. The compiler knows that i is a constant, so it directly uses an immediate value when outputting. It is useless if you change the original value. . .
The following is the assembly code generated by g++ 4.8, which can be understood at a glance. .
.LC0:
.string " "
.text
.globl main
.type main, @function
main:
.LFB1196:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
pushl %ebx
andl $-16, %esp
subl , %esp
.cfi_offset 3, -12
movl , 20(%esp) // i
leal 20(%esp), %eax
movl %eax, 28(%esp) // pc
movl 28(%esp), %eax
movl %eax, 24(%esp) // p
movl 24(%esp), %eax
movl , (%eax) // *p = 1;
movl 24(%esp), %eax
movl (%eax), %ebx //值放到ebx备用
movl 28(%esp), %eax
movl (%eax), %eax
movl %eax, 4(%esp) //参数 *pc
movl $_ZSt4cout, (%esp) //参数 cout
call _ZNSolsEi
movl $.LC0, 4(%esp) // ""
movl %eax, (%esp) // cout
call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
movl %ebx, 4(%esp) //*p
movl %eax, (%esp) // cout
call _ZNSolsEi
movl $.LC0, 4(%esp) //""
movl %eax, (%esp) //cout
call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc
movl , 4(%esp) // !!! 编译器直接使用了立即数32,你改变原来的值没有用
movl %eax, (%esp) // cout
call _ZNSolsEi
movl $_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_, 4(%esp)