搜尋

首頁  >  問答  >  主體

c++ - 有关const_cast的一个疑惑?

  1. 描述你的问题
    pc是一个指向i的const指针,通过const_cast我们得到了一个普通的指针p。直接输出pc,p,以及&i,输出的都是003BF800,但是输出*pc,i却有1和32两种结果,那么请问在003BF800这个地址中存放的到底是整数1还是整数32,以及为什么会出现这种现象?

  2. 贴上相关代码

    #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;

    }

  3. 贴上报错信息

  4. 贴上相关截图

  5. 已经尝试过哪些方法仍然没解决(附上相关链接)

大家讲道理大家讲道理2803 天前365

全部回覆(3)我來回復

  • 黄舟

    黄舟2017-04-17 13:26:38

    003BF800中,保存的確是整數1,由於p指標已改變了其值。然而緣何i的值為32,可能因為i是個編譯時可計算的常數表達式"constexpr",在編譯時已替換了相關內容。

    回覆
    0
  • 迷茫

    迷茫2017-04-17 13:26:38

    透過const_cast移除const限定符後獲得的新變量,如果對應原始變數是非常量(nonconst)類型的,則可以更改新變數。如果原始變數是常數類型的,則更改新變數是未定義的行為。具體情況由編譯器決定。

    題主透過指標p改寫原始變數i是未定義行為。

    回覆
    0
  • PHPz

    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)

    回覆
    0
  • 取消回覆