C ++ Const_Cast是否会引发新变量?

时间:2012-10-19 19:28:47

标签: c++ const-cast

#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和&amp; a是相同的。我很困惑......

你能帮我理解这种情况吗?

非常感谢!

2 个答案:

答案 0 :(得分:6)

未定义的行为意味着任何事情都可能发生。包括这个。

5.2.11 Const cast [expr.const.cast]

  

7)[注意:根据对象的类型,通过指针,左值或指针进行写操作   从const_cast生成的数据成员转出const限定符 73 可能会产生未定义   行为(7.1.6.1)。 - 后注]

潜在的原因可能是编译器看到a const的方式,将cout << "a is " << a << endl;优化为简单的cout << "a is " << 2 << endl;

例如,即使在调试版本中,我也会得到:

        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的值。

答案 1 :(得分:1)

这是你误入歧途的地方:

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

在这里的最后一行,你已经指定了一个变量,一个指向实际上是const 的指针。也就是说,aconstp2指向a。即使通过a,也无法在不调用未定义行为的情况下更改p2的值。