lcl1026504480 发表于 2019-3-14 14:51:11

关于c++常量修改的问题

#include <iostream>
using namespace std;
int main(int argc, char const *argv[])
{
    /* code */
    const int a=1;
    cout <<&a<<endl;
    int *p=(int *)&a;
    *p=20;
    cout << a<<endl<<&a<<endl<<p<<endl<<*p<<endl<<*(&a)<<endl;
    return 0;
}

我用的是MinGW-W64,这个a打印出来是1,但是*&a是20,???/

lcl1026504480 发表于 2019-3-14 15:00:43

这个是编译器的问题吗?

Croper 发表于 2019-3-14 15:02:51

我记得是因为现在很多编译器在编译时会将能够在编译期间就能确定的常量值替换为相应的字面值,作为代码优化的一部分;
但这个是编译器相关的,不同的编译器可能有不同的做法

lcl1026504480 发表于 2019-3-14 15:06:25

Croper 发表于 2019-3-14 15:02
我记得是因为现在很多编译器在编译时会将能够在编译期间就能确定的常量值替换为相应的字面值,作为代码优化 ...

感觉常量编译器相当于生成了字典吧,他根本不是通过地址得到常量的值的,而是仅仅通过变量名

jackz007 发表于 2019-3-14 15:07:25

      我想这样来理解,a 是只读变量,虽然可以通过指针修改这个变量所占用的内存,但是,如果通过 a 来访问这个变量,它仍然还是
1,因为这个变量是只读的,如果通过指针来访问,就会正常访问到你所修改过的值。

lcl1026504480 发表于 2019-3-14 15:12:22

jackz007 发表于 2019-3-14 15:07
我想这样来理解,a 是只读变量,虽然可以通过指针修改这个变量所占用的内存,但是,如果通过 a 来访 ...

感觉编译器是把常量转化为宏定义了吧

lcl1026504480 发表于 2019-3-14 15:12:55

lcl1026504480 发表于 2019-3-14 15:12
感觉编译器是把常量转化为宏定义了吧

可以反汇编看一看的

Croper 发表于 2019-3-14 15:18:13

        cout << a << endl << &a << endl << p << endl << *p << endl << *(&a) << endl;
002E6B27mov         esi,esp
002E6B29push      offset std::endl<char,std::char_traits<char> > (02E1410h)
002E6B2Emov         edi,esp
002E6B30push      1
002E6B32mov         ebx,esp
002E6B34push      offset std::endl<char,std::char_traits<char> > (02E1410h)
002E6B39mov         eax,esp
002E6B3Bmov         ecx,dword ptr
002E6B3Emov         edx,dword ptr
002E6B40push      edx
002E6B41mov         ecx,esp
002E6B43push      offset std::endl<char,std::char_traits<char> > (02E1410h)
002E6B48mov         edx,esp
002E6B4Amov         dword ptr ,esi
002E6B50mov         esi,dword ptr
002E6B53push      esi
002E6B54mov         esi,esp
002E6B56push      offset std::endl<char,std::char_traits<char> > (02E1410h)
002E6B5Bmov         dword ptr ,edi
002E6B61mov         edi,esp
002E6B63mov         dword ptr ,ebx
002E6B69lea         ebx,
002E6B6Cpush      ebx
002E6B6Dmov         ebx,esp
002E6B6Fpush      offset std::endl<char,std::char_traits<char> > (02E1410h)
002E6B74mov         dword ptr ,eax
002E6B7Amov         eax,esp
002E6B7Cpush      1
002E6B7Emov         dword ptr ,ecx
002E6B84mov         ecx,dword ptr
002E6B8Amov         dword ptr ,eax
002E6B90mov         dword ptr ,edx
002E6B96call      dword ptr
002E6B9Cmov         ecx,dword ptr
002E6BA2cmp         ecx,esp
002E6BA4call      __RTC_CheckEsp (02E1276h)
002E6BA9mov         ecx,eax
002E6BABcall      dword ptr
002E6BB1cmp         ebx,esp
002E6BB3call      __RTC_CheckEsp (02E1276h)
002E6BB8mov         ecx,eax
002E6BBAcall      dword ptr
002E6BC0cmp         edi,esp
002E6BC2call      __RTC_CheckEsp (02E1276h)
002E6BC7mov         ecx,eax
002E6BC9call      dword ptr

在vs2017下这一句的反汇编结果,可以看到,这几个地方直接push的是1,也就是直接把字面值给push进去了

jackz007 发表于 2019-3-14 15:20:10

lcl1026504480 发表于 2019-3-14 15:12
感觉编译器是把常量转化为宏定义了吧

      可是 & a 的确取到了变量地址,这样来看,应该不是宏定义。
页: [1]
查看完整版本: 关于c++常量修改的问题