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]

7) [注意:根据对象的类型,通过指针、左值或指向数据成员的指针的写操作由const_cast丢弃 const 限定符73可能产生未定义的行为 (7.1.6.1)。——尾注]

根本原因可能是编译器在查看aisconst后优化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;

在此处的最后一行,您为变量 thu 分配了一个指针,该指针指向实际上是 const的东西。也就是说,aconstp2指向a. a即使p2不调用未定义行为,您也无法更改 的值。

于 2012-10-19T19:37:26.557 回答