C 的內部鏈結與外部鏈結問題

2021-07-29 16:51:47 字數 2624 閱讀 2376

在說內部連線與外部連線前,先說明一些概念。     

1.宣告   

乙個宣告將乙個名稱引入乙個作用域; 在c++中,在乙個作用域中重複乙個宣告是合法的,以下都是宣告:          

class bar;                   //類前置宣告  

typedef int int;             //typedef 宣告    

extern int g_var;           //外部引用宣告     

friend test;                 //友員宣告    

using std::cout;             //命名空間引用宣告     

int foo(int,int);           //函式前置宣告     

在同乙個作用域中你可以多次重複這些宣告。   有兩種宣告不能重複,那就是類成員函式及靜態資料成員的宣告    

class foo    ; 

2.定義

乙個定義提供乙個實體(型別、例項、函式)在乙個作用域的唯一描述。在同一作用域中不可重複定義乙個實體。以下都是定義:     

int y; 

class foo; 

struct bar;

foo * p;

static int i;

enum color;

const double pi=3.1415;

union rep;

void test(int p){};

foo a;

bar b;

下面來看內部連線和外部連線    

1.內部連線:如果乙個名稱對於它的編譯單元來說是區域性的,並且在連線時不會與其它編譯單元中的同樣的名稱相衝突,那麼這個名稱有內部連線(注:有時也將宣告看作是無連線的,這裡我們統一看成是內部連線的)。以下情況有內部連線:  

a)所有的宣告  

b)命名空間(包括全域性命名空間)中的靜態自由函式、靜態友元函式、靜態變數的定義  

c) enum定義 

d)inline函式定義(包括自由函式和非自由函式)  

e)類的定義  

f)命名空間中const常量定義  

g)union的定義

a)類非inline函式總有外部連線(包括類成員函式和類靜態成員函式);  

b)類靜態成員變數總有外部連線;  

c)命名空間(包括全域性命名空間)中非靜態自由函式、非靜態友元函式及非靜態變數。

下面舉例說明:  

a)宣告、enum定義、union定義有內部連線

所有的宣告、enum定義及union定義在編譯後不會產生連線符號,也就是在不同編譯單元中   有相同名稱的宣告及enum、union定義並不會在連線時發生發現多個符號的錯誤。

// main.cpp  

typedef int int; //typedef 宣告,內部連線  

enum color; //enum定義,內部連線  

union x          //union定義,內部連線    

;  int main(void)

// a.cpp  

typedef int int; //在a.cpp中重宣告乙個int型別別名,在連線時不會發生錯誤  

enum color; //在a.cpp中重定義了乙個enum color,在連線時不會發生錯誤  

const int i =blue; //const常量定義,內部連線  

union x            //union定義,內部連線    

;b)命名空間中靜態自由函式、靜態友元函式、靜態變數、const常量定義有內部連線  

// main.cpp  

namespace test    

//命名空間靜態函式定義,內部連線    

}  static int i = 0; //全域性靜態變數定義,內部連線 

static int foo() //全域性靜態函式定義,內部連線  

const int k = 0; //全域性const常量定義,內部連線  

int main(void)    

namespace test    

//命名空間函式定義,外部連線

}int i = 0; //全域性變數定義,外部連線     

int k = 0; //全域性變數定義,外部連線     

int foo()     //全域性函式定義,外部連線

在全域性命名空間中,main.cpp中定義了靜態變數i,常量k,及靜態自由函式foo等,這些都有   內部連線。如果你將這些變數或函式的static或是const修飾符去掉,在連線時就會出現   multiply defined symbols錯誤,它們與a.cpp中的全域性變數、全域性函式發生衝突。

c)類定義總有內部連線,而非inline類成員函式定義總有外部連線,不論這個成員函式是靜態   、虛擬還是一般成員函式,類靜態資料成員定義總有外部連線。這樣當你include了某個類的標頭檔案,使用這個類的函式時,就能連線到正確的類成員函式上。

d)類的靜態資料成員有外部連線,當你在main.cpp中定義了類靜態資料成員,其它編譯單元若使用了,就會連線到main.cpp對應編譯單元的靜態成員變數。 

e)inline函式總有內部連線,不論這個函式是什麼函式。

c 內部鏈結 外部鏈結

c 內部鏈結與外部鏈結 2009年03月12日 星期四 11 07 在說內部連線與外部連線前,先說明一些概念。1.宣告 乙個宣告將乙個名稱引入乙個作用域 在c 中,在乙個作用域中重複乙個宣告是合法的 以下都是宣告 int foo int,int 函式前置宣告 typedef int int type...

C 中的內部鏈結和外部鏈結

c 中的內部連線與外部連線 apr 22nd,2007 by king 一.在學習內部連線與外部連線之前,必須先弄清楚幾個概念 1.宣告 乙個宣告將乙個名稱引入乙個作用域。在c 中,在乙個作用域中重複乙個宣告是合法的。以下都是宣告 int foo int,int 函式前置宣告 typedef int...

C 中的內部鏈結屬性。。。

template class myclass char const s hello myclassx error s is pointer to object with internal linkage 這裡 hello 是個內部鏈結 internal linkage 物件 但是 template ...