變數的連結性
連結性(linkage)描述了名稱如何在不同單元間共享。連結性為外部的名稱,可在檔案間共享,連線性為內部的名稱,只能由一個檔案中的函式共享。自動變數的名稱沒有連結性,因為它不能共享。
連結性為外部的變數,通常簡稱為外部變數,它們的存儲持續性為靜態,作用域為整個檔案。
靜態連結性
靜態連結性(static linkage)也稱為內部連結性(internal linkage)。static關鍵字在C/C++中限定名字在一個函式內或一個編譯單元內可見。(C++ 98/C++03廢棄這一用法,用匿名命名空間取代。但C++11又恢復了這一用法)。
C++隱式把具有const限定的命名空間中的變數處理為內部連結性,除非在const限定聲明之時或之前已經聲明為extern。這與C語言完全不同。
具有內部連結性的:
具有內部連結性的名字,在編譯後不會產生連結符號(或者稱修飾名字),因此不與連結器打交道。
外部連結性
外部連結性(external linkage)也稱為全局連結性(global linkage)。具有全局連結性的名字可以在不同編譯單元聲明並綁定到同一實體。
具有外部連結性的:
無連結性
無連結性(no linkage)的名字具有局部作用域。如局部變數、函式形參等。
跨語言連結
不同程式語言對同一名字編譯後得到的修飾名字可能不同。為了讓C++語言寫的程式能使用C語言程式,需要使用extern "C"使得這段代碼可連結。
示例
/* file demo1.c */ /* extern */ void foo(void); /* extern optional - it's the default */ int main(void){ foo(); return 0; }
/* file demo2.c */ void foo(void){ /* ... */}
函式的連結性
在默認情況下,函式的連結性為外部的,即可以在檔案間共享。可以在函式原型中使用關鍵字extern來指出函式是在另一個檔案中定義的,不過這是可選的。
可以使用關鍵字static將函式的連結性設定為內部的,使之只能在一個檔案中使用。必須同時在原型和函式定義中使用static關鍵字。
static int fn(double x); ...static int fn(double x){ ...}
這意味著該函式只在這個檔案中可見,還意味著可以在其他檔案中定義同名的函式。和變數一樣,在定義靜態函式的檔案中,靜態函式將覆蓋外部定義,因此,即使在外部定義了同名的函式,該檔案扔將使用靜態函式。
單定義規則也適用於非內聯函式,因此對於每個非內聯函式,程式只能包含一個定義。對於連結性味外部的函式來說,這意味著在多檔案程式中,只能有一個檔案包含該函式的定義,但使用該函式的每個檔案都應包含其函式原型。
內聯函式不受這種規則的約束,這允許程式設計師能夠將內聯函式的定義放在頭檔案中,這樣包含了頭檔案的每個檔案都有內聯函式的定義。然而,C++要求同一個函式的素有內聯定義都必須相同。
所有聲明都具有外部連結性
具有內部連線性的定義
名字空間(包括全局名字空間)中的靜態自由函式,靜態友元函式、靜態變數定義,const常量定義;enum定義,類的定義,union的定義;inline函式定義(包括自由函式和非自由函式)。
具有外部連線性的定義
非inline的類成員函式,非inline的類靜態函式;類靜態成員變數;名字空間(包括全局名字空間)中非靜態自由函式,非靜態友元函式,非靜態變數。