EasyC++,函數(shù)和語言鏈接性
大家好,我是梁唐。
想要追求更好閱讀體驗的同學(xué),可以點擊「閱讀原文」訪問github倉庫。
const
關(guān)于const的含義和使用我們之前已經(jīng)討論過了,但const限定符對于默認存儲類型是有影響的。
在默認情況下,全局變量的鏈接性是外部的,也就是說所有文件均可使用。但const全局變量的鏈接性是內(nèi)部的,也就是說只能在本文件當中使用。全局const定義就好像使用了static說明符一樣。
這個設(shè)定看起來有些令人費解,其實是編譯器中的一個優(yōu)化。因為我們常常將一組常量放在頭文件當中,并且在多個文件當中include這個頭文件。如果const聲明的鏈接性也是外部的,根據(jù)單定義規(guī)則,這會出錯。正是為了避免這種情況發(fā)生,所以編譯器做了優(yōu)化,規(guī)定了const關(guān)鍵字修飾的全局變量,鏈接性也為內(nèi)部。
如果出于某種原因,程序員希望某個常量的鏈接性為外部的,可以使用extern關(guān)鍵字來覆蓋默認的內(nèi)部鏈接性:
- extern const int states = 30;
在這種情況下,必須所有使用了該常量的文件中使用extern關(guān)鍵字來聲明它。然而,由于const在多個文件之間共享,因此只有一個文件可以對它進行初始化。
函數(shù)和鏈接性
和變量一樣,函數(shù)也有鏈接性。和C語言一樣,C++不允許在一個函數(shù)當中定義另外一個函數(shù),因此所有函數(shù)的存儲持續(xù)性都默認是靜態(tài)的,即在整個程序運行期間都一直存在。
在默認情況下,函數(shù)的鏈接性是外部的,也就是說可以跨文件使用。我們可以使用關(guān)鍵字static來講函數(shù)的鏈接性設(shè)置成內(nèi)部的,這樣就只有當前文件可以使用。
我們必須同時在原型和定義當中使用static:
- static void test();
- static void test() {
- return ;
- }
單定義規(guī)則對于函數(shù)也一樣適用,也就是說對于非內(nèi)聯(lián)性函數(shù)來說,程序只能包含一個定義。對于鏈接性為外部的函數(shù),只有一個文件包含該函數(shù)的定義。但使用該函數(shù)的每個文件,都應(yīng)該包含函數(shù)的原型。
簡單來說,這就是為什么我們通常將函數(shù)的原型寫在頭文件當中,而實現(xiàn)單獨放在另外一個cpp文件中的原因。因為這樣,所有include該頭文件的文件都包含了函數(shù)的原型,但只有對應(yīng)的cpp文件擁有函數(shù)的定義。這樣就保證了一定不會違反單定義規(guī)則。
語言鏈接性
背景知識:鏈接程序要求每個不同的函數(shù)擁有不同的符號名,比如C語言編譯器可能將spiff函數(shù)翻譯成_spiff,這被稱為C語言鏈接性。而C++當中,同一個名稱可以對應(yīng)多個函數(shù)(函數(shù)重載),因此必須將這些函數(shù)翻譯成不同的名稱。
比如spiff(int)可能翻譯成_spiff_i,spiff(double, double)翻譯成_spiff_d_d。這種方法被稱為C++語言鏈接。
如果要在C++程序當中使用C庫中預(yù)編譯的函數(shù)可能就會名稱對不上,所以為了解決這個問題,我們可以用函數(shù)原型來指出要使用的約定:
- extern "C" void spiff(int);
- extern void spoff(int);
- extern "C++" spaff(int);
第一個原型使用的C語言鏈接性,后面兩個使用的都是C++語言鏈接性。只不過第二個是通過默認方式實現(xiàn)的,而第三個是顯式指出的。
本文轉(zhuǎn)載自微信公眾號「Coder梁」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系Coder梁公眾號。