鏈接性是程序編譯時,程序中的名字(name,也可稱標識符identifier)在作用域中不同位置的出現能夠綁定到同一對象或函數。C++語言中,鏈接性描述了名字在整個程序或單獨編譯單元中能否綁定到同一實體(entity)。
變量的鏈接性鏈接性(linkage)描述了名稱如何在不同單元間共享。鏈接性為外部的名稱,可在文件間共享,連接性為內部的名稱,只能由一個文件中的函數共享。自動變量的名稱沒有鏈接性,因為它不能共享。
鏈接性為外部的變量,通常簡稱為外部變量,它們的存儲持續(xù)性為靜態(tài),作用域為整個文件。
靜態(tài)鏈接性靜態(tài)鏈接性(static linkage)也稱為內部鏈接性(internal linkage)。static關鍵字在C/C++中限定名字在一個函數內或一個編譯單元內可見。(C++ 98/C++03廢棄這一用法,用匿名命名空間取代。但C++11又恢復了這一用法)。
C++隱式把具有const限定的命名空間中的變量處理為內部鏈接性,除非在const限定聲明之時或之前已經聲明為extern。這與C語言完全不同。
具有內部鏈接性的:
所有的聲明
命名空間(包括全局命名空間)中的靜態(tài)自由函數、靜態(tài)友元函數、靜態(tài)變量的定義、const常量定義
enum定義
inline函數定義(包括自由函數和非自由函數)
類(class、struct、union)的定義
具有內部鏈接性的名字,在編譯后不會產生鏈接符號(或者稱修飾名字),因此不與鏈接器打交道。
外部鏈接性外部鏈接性(external linkage)也稱為全局鏈接性(global linkage)。具有全局鏈接性的名字可以在不同編譯單元聲明并綁定到同一實體。1
具有外部鏈接性的:
非inline函數。包括命名空間中非靜態(tài)函數、類成員函數和類靜態(tài)成員函數
類靜態(tài)成員變量總有外部鏈接。
命名空間(不包括無名命名空間)中非靜態(tài)變量
無鏈接性無鏈接性(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){ ...}這意味著該函數只在這個文件中可見,還意味著可以在其他文件中定義同名的函數。和變量一樣,在定義靜態(tài)函數的文件中,靜態(tài)函數將覆蓋外部定義,因此,即使在外部定義了同名的函數,該文件扔將使用靜態(tài)函數。
單定義規(guī)則也適用于非內聯函數,因此對于每個非內聯函數,程序只能包含一個定義。對于鏈接性味外部的函數來說,這意味著在多文件程序中,只能有一個文件包含該函數的定義,但使用該函數的每個文件都應包含其函數原型。
內聯函數不受這種規(guī)則的約束,這允許程序員能夠將內聯函數的定義放在頭文件中,這樣包含了頭文件的每個文件都有內聯函數的定義。然而,C++要求同一個函數的素有內聯定義都必須相同。
所有聲明都具有外部鏈接性具有內部連接性的定義名字空間(包括全局名字空間)中的靜態(tài)自由函數,靜態(tài)友元函數、靜態(tài)變量定義,const常量定義;enum定義,類的定義,union的定義;inline函數定義(包括自由函數和非自由函數)。
具有外部連接性的定義非inline的類成員函數,非inline的類靜態(tài)函數;類靜態(tài)成員變量;名字空間(包括全局名字空間)中非靜態(tài)自由函數,非靜態(tài)友元函數,非靜態(tài)變量。
本詞條內容貢獻者為:
李岳陽 - 副教授 - 江南大學