朝花夕拾:const關(guān)鍵字的要點(diǎn)和實(shí)現(xiàn)機(jī)制

C Programming Language.png

0x00 最初的起點(diǎn)

首先是一道爛大街的題目:以下四個(gè)變量有什么區(qū)別?

Problem.png

答案很簡(jiǎn)單:

1. v1是一個(gè)指針常量,即指針?biāo)赶虻闹挡豢筛淖?,但是指針?biāo)赶虻牡刂房梢愿淖儭?/h5>
2. v2和v1相同。
3. v3是一個(gè)常量指針,即指針?biāo)赶虻膬?nèi)存地址不可改變。
4. v4是一個(gè)指向常量的常量指針,即無論是指向的內(nèi)存地址,還是內(nèi)存地址中的值都是不可改變的。

可以看到,這個(gè)基本上就是依靠記憶的東西,并沒有什么理解上的難點(diǎn),只是記住之后沒過一段時(shí)間可能就又混淆了。

記憶方案一

1.如果const位于的左側(cè),則const就是用來修飾指針?biāo)赶虻淖兞浚粗羔樦赶驗(yàn)槌A浚?br> 2.如果const位于的右側(cè),則const就是修飾指針本身,即指針本身是常量。

恩... 似乎很有規(guī)律的樣子,但是我記性很差,這種規(guī)則對(duì)我來說還是太繞,過一段時(shí)間就不確定會(huì)不會(huì)記反了。

記憶方案二

Bjarne在他的The C++ Programming Language里面給出過一個(gè)助記的方法:

把一個(gè)聲明從右向左讀。

char * const cp; ( * 讀成 pointer to )
cp is a const pointer to char

const char * p;
p is a pointer to const char;

恩。這樣確實(shí)大大的降低了記混的情況了,但是雖然這種方法已經(jīng)很簡(jiǎn)單了,但是對(duì)于英語不是母語的人來說,還是需要繞一層的,那么有什么更加簡(jiǎn)單的記憶方法嗎?

記憶方案三

const修飾前面的關(guān)鍵字,只有當(dāng)const開頭時(shí)才修飾后面的關(guān)鍵字

即:當(dāng)const前面是char int之類的類型關(guān)鍵字時(shí),表示修飾的是指針?biāo)赶虻膬?nèi)容;而當(dāng)前面的是指針運(yùn)算符(*)的時(shí)候,那么表示修飾的是該指針;當(dāng)const位于表達(dá)式首位時(shí),請(qǐng)參考第一條。

0X01實(shí)現(xiàn)機(jī)制

其實(shí)const關(guān)鍵字并沒有多么復(fù)雜的實(shí)現(xiàn)方法,只是在編譯器的層面做了modify的限制,而const變量和非const變量在runtime期間其實(shí)并無卵分別,最好的證據(jù)就是編譯過程中的匯編代碼了,證據(jù)如下:

首先我們有兩段簡(jiǎn)單到媽都不認(rèn)得的C++代碼:

代碼一

#include <iostream>
using namespace std;

int main()
{
    int a = 100;
    return 0;
}

代碼二


#include <iostream>
using namespace std;

int main()
{
    const int a = 100;
    return 0;
}


這兩段代碼唯一的區(qū)別就是,一個(gè)int變量有const修飾,而另一個(gè)int變量沒有const修飾。OK,接下來我們編譯成匯編,使用下面的命令:

g++ -S demo.cpp

編譯之后得到的匯編代碼對(duì)比圖如下所示:

匯編代碼對(duì)比.png

我們可看到,兩者并無什么不同,也就是說,匯編并不會(huì)對(duì)const的變量做什么特殊的處理,const只是在編譯的層面給程序做了限制。

但是,這里又有一個(gè)問題,當(dāng)我們把代碼修改成下面那樣的時(shí)候:

代碼一

#include <iostream>
using namespace std;

int main()
{
    int a = 100;
    cout << a << endl;
    return 0;
}

代碼二


#include <iostream>
using namespace std;

int main()
{
    const int a = 100;
    cout << a << endl;
    return 0;
}


這里的代碼與上面的代碼的區(qū)別無非是,訪問了a的值,按照上面的理論,編譯后的代碼應(yīng)該沒有不同,但是世事難料,對(duì)比圖如下:

g++編譯下對(duì)比.png

我們可以看到竟然還是存在差別的,但是根據(jù)查閱資料和個(gè)人猜測(cè),我認(rèn)為可能的原因是:const的變量存儲(chǔ)的時(shí)候確實(shí)沒有特殊處理,但是在取值時(shí),并不會(huì)訪問const變量的內(nèi)存地址,而是通過一個(gè)全局符號(hào)表(symbol table)替換了該值,所以才會(huì)出現(xiàn)這樣的匯編代碼的差別。

0X02 最后說的話

說到底還是不懂匯編,有空也可以研究一下,如果有匯編大神路過,也請(qǐng)不吝賜教!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容