求帮忙解释一下下面的代码:
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
请按任意键继续. . .
有编译器优化,进行了数据暂存,加volatile修饰,强制每次由内存读取数据。
加上volatile关键字之后地址确实不一样。这个是编译器优化的原因吧。
@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的地址。
@Wang Hui: 感谢