複製鏈接
請複製以下鏈接發送給好友

鏈接性

鎖定
鏈接性是程序編譯時,程序中的名字(name,也可稱標識符identifier)在作用域中不同位置的出現能夠綁定到同一對象或函數。C++語言中,鏈接性描述了名字在整個程序或單獨編譯單元中能否綁定到同一實體(entity)。
中文名
鏈接性
外文名
linkage
領    域
計算機編程

鏈接性變量的鏈接性

鏈接性(linkage)描述了名稱如何在不同單元間共享。鏈接性為外部的名稱,可在文件間共享,連接性為內部的名稱,只能由一個文件中的函數共享。自動變量的名稱沒有鏈接性,因為它不能共享。
鏈接性為外部的變量,通常簡稱為外部變量,它們的存儲持續性為靜態,作用域為整個文件。

鏈接性靜態鏈接性

靜態鏈接性(static linkage)也稱為內部鏈接性(internal linkage)。static關鍵字在C/C++中限定名字在一個函數內或一個編譯單元內可見。(C++ 98/C++03廢棄這一用法,用匿名命名空間取代。但C++11又恢復了這一用法)。
C++隱式把具有const限定的命名空間中的變量處理為內部鏈接性,除非在const限定聲明之時或之前已經聲明為extern。這與C語言完全不同。
具有內部鏈接性的:
  • 所有的聲明
  • 命名空間(包括全局命名空間)中的靜態自由函數、靜態友元函數、靜態變量的定義、const常量定義
  • enum定義
  • inline函數定義(包括自由函數和非自由函數)
  • 類(class、struct、union)的定義
具有內部鏈接性的名字,在編譯後不會產生鏈接符號(或者稱修飾名字),因此不與鏈接器打交道。

鏈接性外部鏈接性

外部鏈接性(external linkage)也稱為全局鏈接性(global linkage)。具有全局鏈接性的名字可以在不同編譯單元聲明並綁定到同一實體。 [1] 
具有外部鏈接性的:
  • 非inline函數。包括命名空間中非靜態函數、類成員函數和類靜態成員函數
  • 類靜態成員變量總有外部鏈接。
  • 命名空間(不包括無名命名空間)中非靜態變量

鏈接性無鏈接性

無鏈接性(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的類靜態函數;類靜態成員變量;名字空間(包括全局名字空間)中非靜態自由函數,非靜態友元函數,非靜態變量。
參考資料
  • 1.    王麗偉. 基於鏈接的網絡計量指標與科學評價[D]. 吉林大學, 2006.