描述你的问题
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
在003BF800
中,保存的確是整數1,由於p
指標已改變了其值。然而緣何i的值為32,可能因為i是個編譯時可計算的常數表達式"constexpr
",在編譯時已替換了相關內容。
迷茫2017-04-17 13:26:38
透過const_cast
移除const
限定符後獲得的新變量,如果對應原始變數是非常量(nonconst
)類型的,則可以更改新變數。如果原始變數是常數類型的,則更改新變數是未定義的行為。具體情況由編譯器決定。
題主透過指標p
改寫原始變數i
是未定義行為。
PHPz2017-04-17 13:26:38
這個沒什麼奇怪的,編譯器知道i是常數,所以輸出的時候直接用了立即數來輸出,你改變了原來的值根本沒有用。 。 。
下面是g++ 4.8產生的彙編程式碼,一看便知。 。
.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)