標籤:bug 有一個 特定 資料 先行編譯 uil ant 統一 track
一、文章來由
const具體解釋之二
二、const 取代 #define
const最初動機就是取代 #define。
const 優於 #define:
(1) #define沒有類型檢查,const在編譯期(而不是先行編譯期)做類型檢查。
(2)const方便調試和定位bug。
所以應該全然用const取代#define
三、標頭檔裡的const
(1)要使用const取代#define。相同須要把const定義放進標頭檔(或其它格式檔案,include就可以)。
這樣通過包括標頭檔。可把const定義單獨放在一個地方並把它分配給一個編程單元。
(2)C++中的const默覺得內部串連(internal linkage),也就是說 const 僅在被定義過的檔案裡才可見,而在串連時不能被其它
url=Lo9O57v2QfNPo448tsFG0ohDjltQti7bZzkVdj5AZfTf0UmOpLWtCxRIS8IHzjonYh1CBOZ1M4XyNtjylIkzU_">編譯單元看到。
可是在c中只在還有一個檔案裡定義(不用extern修飾),還有一個檔案也是合法的。c中const是必需分配記憶體的,而c++實際上一開始是不會分配記憶體的,不過存在字元表中。
//another.cconst int a = 5;//other.c#include <stdio.h>int main(){ extern const int a; printf("%d\n",a); return 0;}
(3)定義一個const時。必須賦一個值給它,除非用extern做說明:extern const int bufsize;
四、常量摺疊(constant folding)
通常C++編譯器並不為const建立儲存空間,相反它把這個定義儲存在它的符號表裡,但extern強制進行了儲存空間分配。取const地址也會**,這也解釋了const具體解釋(一)中可以改動const空間。可是cout原值相當於還是去符號表中找。
由於extern意味著使用外部串連(定義時使用extern),因此必須分配儲存空間,這也就是說有幾個不同的編譯單元應當可以引用它,所以必須有儲存空間。
通常情況下,當extern不是定義的一部分時,不會分配儲存空間。假設使用const,那麼編譯時間會進行常量摺疊。
那同檔案extern呢
extern const int a;int main(){ //freopen("input.txt","r",stdin); cout<<a<<endl; return 0;}const int a = 66;
由於extern不是定義的一部分,所以個人覺得這也不會分配空間。
五、為什麼const要內部串連
當然想絕對不為不論什麼const分配儲存是不可能的,尤其是複雜的結構。所以const的定義必須預設內部串連,即串連僅在特定的編譯單元內;否則。由於眾多的const在多個cpp檔案分配記憶體,引起串連錯誤。
串連程式在多個對象檔案看到統一的定義就會“抱怨”。
然而,由於const預設內部串連,所以串連程式不會跨過編譯單元串連那些定義,因此不會有衝突。
參考資料
[1] c++編程思想
[2] http://blog.csdn.net/bestrivenfan/article/details/50951809
C++進階進階 第四季:const具體解釋(二) 常量摺疊