標籤:
在c中const這個關鍵字,維基給出這樣一句話
When applied in an object declaration,[b] it indicates that the object is a constant: its value does not change, unlike a variable. This basic use – to declare constants – has parallels in many other languages
實際就是用於不允許修改其值的,但是這裡需要思考的就是,不允許修改的a的值還是記憶體裡的值,如果非要修改記憶體裡的值怎麼辦?cpu只認識0101,編譯器是如何完成const的功能的,下面通過實驗分析一下,(實驗平台64位win7,vs2008)
初始代碼
int main(){ int b,c; const int a=10; c=1; return 0;}
很常見,如果
a=11;首先編譯不通過,這是c文法就不允許的。
看看此時a對應的記憶體裡面的值,
如果想修改一個值,還有一種方式就是指標間接完成。然後修改代碼
int main(){ int b,c; const int a=10; int *p=(int*)&a; *p=11; return 0;}
編譯通過,看看記憶體裡的東西
的確被修改了,
也就是說,繞過編譯器的const修飾規則,依舊可以修改這個記憶體的值。
這裡就會有出現一個問題,修改之後,a也是指向的這個地址,但下次引用a時,難道a不從那個記憶體位址裡面取值嗎
比如下面這種情況
int main(){ int b,c; const int a=10; int *p=(int*)&a; *p=11; c=1; b=a+c; return 0;}
結果b的值為11,也就是說,編譯器在計算a時,並沒有從a所對應的記憶體中去取值。
那編譯器是如何完成的。看看這段代碼的彙編
int b,c; const int a=10;012E1F6E mov dword ptr [a],0Ah int *p=(int*)&a;012E1F75 lea eax,[a] 012E1F78 mov dword ptr [p],eax *p=11;012E1F7B mov eax,dword ptr [p] 012E1F7E mov dword ptr [eax],0Bh c=1;012E1F84 mov dword ptr [c],1 b=a+c;012E1F8B mov eax,dword ptr [c] 012E1F8E add eax,0Ah 012E1F91 mov dword ptr [b],eax return 0;012E1F94 xor eax,eax
主要是這幾句話
b=a+c;012E1F8B mov eax,dword ptr [c]012E1F8E add eax,0Ah012E1F91 mov dword ptr [b],eax
在引用c的值的時候,是從c對應的記憶體中去去資料,然後賦值給寄存器eax,
但是在引用a變數時,並沒有像c一樣,而是直接用10來代替。
臥槽,這不就是宏定義麼,直接將a用它初始化的值就行替換,
用一個對比實驗
#define a_tmp (10)int main(){ int b,c; const int a=10; int *p=(int*)&a; *p=11; c=1; b=a+c; b=a_tmp+c; return 0;}
觀察彙編代碼
b=a+c;01221F8B mov eax,dword ptr [c] 01221F8E add eax,0Ah 01221F91 mov dword ptr [b],eax b=a_tmp+c;01221F94 mov eax,dword ptr [c] 01221F97 add eax,0Ah 01221F9A mov dword ptr [b],eax
一模一樣,這下就明白了。。。。。。。。。。
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
分析編譯器對C關鍵字的處理『跳過編譯器的語法檢查,完成很危險的操作』