1
#include <iostream>

using namespace std;

int main() {
        const int a = 2;
        const int *p = &a;
        int *p2 = const_cast<int*>(p);
        *p2=5;
        char *p3 = (char *)&a;
        cout << "p2 is" << *p2 << endl;
        cout << "p2 address " << p2 << endl;
        cout << "a is " << a << endl;
        cout << "a address " << &a << endl;

        return 0;
}

こんにちは、みんな!

出力によると、* p2とaの値は異なり、* p2は5、aは2です。

ただし、p2と&aは同じです。よくわかりません...

これがどこにあるのか理解するのを手伝ってくれませんか。

どうもありがとうございます!

4

2 に答える 2

6

未定義の動作とは、何でも起こり得ることを意味します。これも含めて。

5.2.11 定数キャスト [expr.const.cast]

const_cast7) [ 注: オブジェクトの型に応じて、const 修飾子をキャストする73から生じるポインター、左辺値、またはデータ メンバーへのポインターを介した書き込み操作は、未定義の動作を生成する可能性があります (7.1.6.1)。—終わりのメモ]

根本的な理由は、コンパイラが の様子を見aて、単純なconstに最適化することである可能性があります。cout << "a is " << a << endl;cout << "a is " << 2 << endl;

たとえば、 debug build でも、次のようになります。

        cout << "a is " << a << endl;
00CE1581  mov         esi,esp  
00CE1583  mov         eax,dword ptr [__imp_std::endl (0CFD30Ch)]  
00CE1588  push        eax  
00CE1589  mov         edi,esp  
//...
00CE158B  push        2 
//...
00CE158D  push        offset string "a is " (0CE7840h)  
00CE1592  mov         ecx,dword ptr [__imp_std::cout (0CFD308h)]  
00CE1598  push        ecx  
00CE1599  call        std::operator<<<std::char_traits<char> > (0CE1159h)  
00CE159E  add         esp,8  
00CE15A1  mov         ecx,eax  
00CE15A3  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0CFD304h)]  
00CE15A9  cmp         edi,esp  
00CE15AB  call        @ILT+415(__RTC_CheckEsp) (0CE11A4h)  
00CE15B0  mov         ecx,eax  
00CE15B2  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (0CFD300h)]  
00CE15B8  cmp         esi,esp  
00CE15BA  call        @ILT+415(__RTC_CheckEsp) (0CE11A4h)  

重要な部分を強調しました -は、読み取られる値ではなく、2の引数スタックに直接プッシュされます。operator<<a

于 2012-10-19T19:30:56.923 に答える
1

これはあなたが迷ったところです:

int main() {
        const int a = 2;
        const int *p = &a;
        int *p2 = const_cast<int*>(p);
        *p2=5;

ここの最後の行では、実際には constである何かを指すポインターに変数を割り当てています。つまり、aですconstp2を指しaます。未定義の動作を呼び出さずに、 をa介しても、 の値を変更することはできません。p2

于 2012-10-19T19:37:26.557 に答える