64: const int a = 2;
00403B3D mov dword ptr [ebp-30h],2
65: int *b = (int *)&a;
00403B44 lea ecx,[ebp-30h]
00403B47 mov dword ptr [ebp-34h],ecx
66: int c=a;
00403B4A mov dword ptr [ebp-38h],2 // 这里,c=a,给的不是a的地址,而是直接是a的值.
//因此,即使 *b 的值变了, c 依然都是a最原始的值...
67: cout << a ;
00403B51 push 2 // 这里也一样,只是a的原始值,而不是*b的值...
00403B53 mov ecx,offset std::cout (0047eea8)
00403B58 call @ILT+905(std::basic_ostream<char,std::char_traits<char> >::operator<<) (0040138e)
68: cout << (*b) ;
00403B5D mov edx,dword ptr [ebp-34h]
00403B60 mov eax,dword ptr [edx]
00403B62 push eax
00403B63 mov ecx,offset std::cout (0047eea8)
00403B68 call @ILT+905(std::basic_ostream<char,std::char_traits<char> >::operator<<) (0040138e)
从上述汇编代码中可以看出,在对const常量进行读取时,编译器会直接用const常量对应的立即数直接替换,而不去访问内存,所以内存,所以即时通过指针对const常量的内存进行了修改,也不会影响const常量输出的值。
如果我们把const int a=2;改为int i=2; const int a=c,则通过*b修改了a的内存空间后,会导致a的值的改变。因为在这种情况下,给a赋值的是变量i,而不是一个整型字面值常量。
参考http://blog.csdn.net/luoyeaijiao/article/details/7982385一文中 firendlys的评论。