首页 新闻 会员 周边 捐助

为何地址一样,值却不一样?

0
[已解决问题] 解决于 2012-05-03 16:02

求帮忙解释一下下面的代码:

 1 #include <iostream>
 2 using namespace std;
 3 
 4 int _tmain(int argc, _TCHAR* argv[])
 5 {
 6     const int a = 1;
 7     int *p = const_cast<int*>(&a);
 8     *p = 2;
 9 
10     cout << "value a="<< a << endl;
11     cout << "value *p=" <<*p << endl;
12     cout << "address a=" <<&a << endl;
13     cout << "address p=" <<p << endl;
14 
15     return 0;
16 }

是因为编译器的优化的原因么?

输出如下:

value a=1
value *p=2
address a=001CF794
address p=001CF794
请按任意键继续. . .

Rollen Holt的主页 Rollen Holt | 菜鸟二级 | 园豆:210
提问于:2012-05-02 12:08
< >
分享
最佳答案
0

有编译器优化,进行了数据暂存,加volatile修饰,强制每次由内存读取数据。

奖励园豆:5
zsounder | 老鸟四级 |园豆:2819 | 2012-05-02 12:17

加上volatile关键字之后地址确实不一样。这个是编译器优化的原因吧。

Rollen Holt | 园豆:210 (菜鸟二级) | 2012-05-02 12:23

@Rollen Holt: 

像你说的,就是编译器优化的结果。

const的时候

 1  const int a = 1;
 2 004114DE  mov         dword ptr [a],1 
 3  int *p = const_cast<int*>(&a);
 4 004114E5  lea         eax,[a] 
 5 004114E8  mov         dword ptr [p],eax 
 6      *p = 2;
 7 004114EB  mov         eax,dword ptr [p] 
 8 004114EE  mov         dword ptr [eax],2 
 9    
10     cout << "value a="<< a << endl;
11 004114F4  mov         esi,esp 
12 004114F6  mov         eax,dword ptr [__imp_std::endl (41A340h)] 
13 004114FB  push        eax  
14 004114FC  mov         edi,esp 
15 004114FE  push        1    
16 00411500  push        offset string "value a=" (41782Ch) 
17 00411505  mov         ecx,dword ptr [__imp_std::cout (41A344h)] 
18 0041150B  push        ecx  
19 0041150C  call        std::operator<<<std::char_traits<char> > (411159h) 
20 00411511  add         esp,8 
21 00411514  mov         ecx,eax 
22 00411516  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (41A348h)] 
23 0041151C  cmp         edi,esp 
24 0041151E  call        @ILT+420(__RTC_CheckEsp) (4111A9h) 
25 00411523  mov         ecx,eax 
26 00411525  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (41A34Ch)] 
27 0041152B  cmp         esi,esp 
28 0041152D  call        @ILT+420(__RTC_CheckEsp) (4111A9h) 
29    cout << "value *p=" <<*p << endl;
30 00411532  mov         esi,esp 
31 00411534  mov         eax,dword ptr [__imp_std::endl (41A340h)] 
32 00411539  push        eax  
33 0041153A  mov         edi,esp 
34 0041153C  mov         ecx,dword ptr [p] 
35 0041153F  mov         edx,dword ptr [ecx] 
36 00411541  push        edx  
37 00411542  push        offset string "value *p=" (417820h) 
38 00411547  mov         eax,dword ptr [__imp_std::cout (41A344h)] 
39 0041154C  push        eax  
40 0041154D  call        std::operator<<<std::char_traits<char> > (411159h) 
41 00411552  add         esp,8 
42 00411555  mov         ecx,eax 
43 00411557  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (41A348h)] 
44 0041155D  cmp         edi,esp 
45 0041155F  call        @ILT+420(__RTC_CheckEsp) (4111A9h) 
46 00411564  mov         ecx,eax 
47 00411566  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (41A34Ch)] 
48 0041156C  cmp         esi,esp 
49 0041156E  call        @ILT+420(__RTC_CheckEsp) (4111A9h) 
50         cout << "address a=" <<&a << endl;
51 00411573  mov         esi,esp 
52 00411575  mov         eax,dword ptr [__imp_std::endl (41A340h)] 
53 0041157A  push        eax  
54 0041157B  mov         edi,esp 
55 0041157D  lea         ecx,[a] 
56 00411580  push        ecx  
57 00411581  push        offset string "address a=" (417810h) 
58 00411586  mov         edx,dword ptr [__imp_std::cout (41A344h)] 
59 0041158C  push        edx  
60 0041158D  call        std::operator<<<std::char_traits<char> > (411159h) 
61 00411592  add         esp,8 
62 00411595  mov         ecx,eax 
63 00411597  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (41A32Ch)] 
64 0041159D  cmp         edi,esp 
65 0041159F  call        @ILT+420(__RTC_CheckEsp) (4111A9h) 
66 004115A4  mov         ecx,eax 
67 004115A6  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (41A34Ch)] 
68 004115AC  cmp         esi,esp 
69 004115AE  call        @ILT+420(__RTC_CheckEsp) (4111A9h) 
70     cout << "address p=" <<p << endl;
71 004115B3  mov         esi,esp 
72 004115B5  mov         eax,dword ptr [__imp_std::endl (41A340h)] 
73 004115BA  push        eax  
74 004115BB  mov         edi,esp 
75 004115BD  mov         ecx,dword ptr [p] 
76 004115C0  push        ecx  
77 004115C1  push        offset string "address p=" (417800h) 
78 004115C6  mov         edx,dword ptr [__imp_std::cout (41A344h)] 
79 004115CC  push        edx  
80 004115CD  call        std::operator<<<std::char_traits<char> > (411159h) 
81 004115D2  add         esp,8 
82 004115D5  mov         ecx,eax 
83 004115D7  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (41A32Ch)] 
84 004115DD  cmp         edi,esp 
85 004115DF  call        @ILT+420(__RTC_CheckEsp) (4111A9h) 
86 004115E4  mov         ecx,eax 
87 004115E6  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (41A34Ch)] 
88 004115EC  cmp         esi,esp 
89 004115EE  call        @ILT+420(__RTC_CheckEsp) (4111A9h) 

输出a的时候,可以看到第15行是直接: push 1,也就是a的数值。

 

volatile的时候:

 1 004114DC  rep stos    dword ptr es:[edi] 
 2  volatile const int a = 1;
 3 004114DE  mov         dword ptr [a],1 
 4  int *p = const_cast<int*>(&a);
 5 004114E5  lea         eax,[a] 
 6 004114E8  mov         dword ptr [p],eax 
 7      *p = 2;
 8 004114EB  mov         eax,dword ptr [p] 
 9 004114EE  mov         dword ptr [eax],2 
10     
11     cout << "value a="<< a << endl;
12 004114F4  mov         esi,esp 
13 004114F6  mov         eax,dword ptr [__imp_std::endl (41A340h)] 
14 004114FB  push        eax  
15 004114FC  mov         edi,esp 
16 004114FE  mov         ecx,dword ptr [a] 
17 00411501  push        ecx  
18 00411502  push        offset string "value a=" (41782Ch) 
19 00411507  mov         edx,dword ptr [__imp_std::cout (41A344h)] 
20 0041150D  push        edx  
21 0041150E  call        std::operator<<<std::char_traits<char> > (411159h) 
22 00411513  add         esp,8 
23 00411516  mov         ecx,eax 
24 00411518  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (41A348h)] 
25 0041151E  cmp         edi,esp 
26 00411520  call        @ILT+420(__RTC_CheckEsp) (4111A9h) 
27 00411525  mov         ecx,eax 
28 00411527  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (41A34Ch)] 
29 0041152D  cmp         esi,esp 
30 0041152F  call        @ILT+420(__RTC_CheckEsp) (4111A9h) 
31    cout << "value *p=" <<*p << endl;
32 00411534  mov         esi,esp 
33 00411536  mov         eax,dword ptr [__imp_std::endl (41A340h)] 
34 0041153B  push        eax  
35 0041153C  mov         edi,esp 
36 0041153E  mov         ecx,dword ptr [p] 
37 00411541  mov         edx,dword ptr [ecx] 
38 00411543  push        edx  
39 00411544  push        offset string "value *p=" (417820h) 
40 00411549  mov         eax,dword ptr [__imp_std::cout (41A344h)] 
41 0041154E  push        eax  
42 0041154F  call        std::operator<<<std::char_traits<char> > (411159h) 
43 00411554  add         esp,8 
44 00411557  mov         ecx,eax 
45 00411559  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (41A348h)] 
46 0041155F  cmp         edi,esp 
47 00411561  call        @ILT+420(__RTC_CheckEsp) (4111A9h) 
48 00411566  mov         ecx,eax 
49 00411568  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (41A34Ch)] 
50 0041156E  cmp         esi,esp 
51 00411570  call        @ILT+420(__RTC_CheckEsp) (4111A9h) 
52         cout << "address a=" <<&a << endl;
53 00411575  mov         esi,esp 
54 00411577  mov         eax,dword ptr [__imp_std::endl (41A340h)] 
55 0041157C  push        eax  
56 0041157D  lea         ecx,[a] 
57 00411580  test        ecx,ecx 
58 00411582  setne       dl   
59 00411585  mov         edi,esp 
60 00411587  movzx       eax,dl 
61 0041158A  push        eax  
62 0041158B  push        offset string "address a=" (417810h) 
63 00411590  mov         ecx,dword ptr [__imp_std::cout (41A344h)] 
64 00411596  push        ecx  
65 00411597  call        std::operator<<<std::char_traits<char> > (411159h) 
66 0041159C  add         esp,8 
67 0041159F  mov         ecx,eax 
68 004115A1  call        dword ptr [MSVCP90D_NULL_THUNK_DATA (41A350h)] 
69 004115A7  cmp         edi,esp 
70 004115A9  call        @ILT+420(__RTC_CheckEsp) (4111A9h) 
71 004115AE  mov         ecx,eax 
72 004115B0  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (41A34Ch)] 
73 004115B6  cmp         esi,esp 
74 004115B8  call        @ILT+420(__RTC_CheckEsp) (4111A9h) 
75     cout << "address p=" <<p << endl;
76 004115BD  mov         esi,esp 
77 004115BF  mov         eax,dword ptr [__imp_std::endl (41A340h)] 
78 004115C4  push        eax  
79 004115C5  mov         edi,esp 
80 004115C7  mov         ecx,dword ptr [p] 
81 004115CA  push        ecx  
82 004115CB  push        offset string "address p=" (417800h) 
83 004115D0  mov         edx,dword ptr [__imp_std::cout (41A344h)] 
84 004115D6  push        edx  
85 004115D7  call        std::operator<<<std::char_traits<char> > (411159h) 
86 004115DC  add         esp,8 
87 004115DF  mov         ecx,eax 
88 004115E1  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (41A32Ch)] 
89 004115E7  cmp         edi,esp 
90 004115E9  call        @ILT+420(__RTC_CheckEsp) (4111A9h) 
91 004115EE  mov         ecx,eax 
92 004115F0  call        dword ptr [__imp_std::basic_ostream<char,std::char_traits<char> >::operator<< (41A34Ch)] 
93 004115F6  cmp         esi,esp 
94 004115F8  call        @ILT+420(__RTC_CheckEsp) (4111A9h) 

输出a的时候,可以看到:

mov         ecx,dword ptr [a] 
push ecx
不再是直接将a的数值1push到流中,而是再次读取内存中a的地址。


zsounder | 园豆:2819 (老鸟四级) | 2012-05-02 13:06

@Wang Hui: 感谢

Rollen Holt | 园豆:210 (菜鸟二级) | 2012-05-03 16:03
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册