C++高級進階 第四季:const詳解(二) 常量折疊


一、文章來由

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 僅在被定義過的文件里才可見,而在連接時不能被其他編譯單元看到。

但是在c中僅僅在另一個文件中定義(不用extern修飾),另一個文件也是合法的。c中const是必需分配內存的,而c++實際上一開始是不會分配內存的,只是存在字符表中。

//another.c
const 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


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com