外部鏈接和內部鏈接,臨時性定義,extern,static

外部鏈接和內部鏈接 參見 https://blog.csdn.net/xiexievv/article/details/8487373 ,非常詳細!

補充1: 不完全聲明

struct s;
union u;
char str[];

編譯器不知道這種類型該佔幾個字節的存儲空間!!
具有不完全類型的變量可以通過多次聲明組合成一個完全類型,比如數組 str 聲明兩次:

char str[];
char str[10];

當編譯器碰到第一個聲明時,認爲 str 是一個不完全類型,碰到第二個聲明時 str 就組合成完全類型了,如果編譯器處理到程序文件的末尾仍然無法把 str 組合成一個完全類型,就會報錯。讀者可能會想,這個語法有什麼用呢?爲何不在第一次聲明時就把 str 聲明成完全類型?有些情況下這麼做有一定的理由,比如第一個聲明是寫在頭文件裏的,第二個聲明寫在 .c 文件裏,這樣如果要改數組長度,只改 .c 文件就行了,頭文件可以不用改。

補充2: int i;

以下:

int i;
int i;

gcc 可以編譯通過:int i; 沒有明確的初始化操作,屬於 臨時性定義(tentative definition) 可以在程序中發生多次發生,但是最後只留一個單獨的實體 。
g++不能編譯通過:int i; 屬於 聲明性定義 ,聲明的同時定義了該變量,不能重複定義變量。 C++ 決不允許重複執行相同的定義或聲明,例如類的定義、struct與enum所定義的自定義類型,所以C++裏面有大量的條件編譯語句(#if#ifdef#elif#else#ifndef#endif#define#undef)。但是類型定義typedef可以重複。

gcc:

int i1 = 1; 	    // definition, external linkage				(gcc,標準的外部鏈接定義)
static int i2 = 2; // definition, internal linkage
extern int i3 = 3;  // definition, external linkage 		     (gcc,不標準的外部鏈接定義,應該去掉extern,否則被警告)
int i4; 		 // tentative definition, external linkage 
static int i5;   // tentative definition, internal linkage
int i1; 		 // valid tentative definition, refers to previous(gcc,允許先定義後臨時性定義)
int i2; 		 // 6.2.2 renders undefined, linkage disagreement (gcc,不允許先內部鏈接定義,再外部鏈接臨時性定義)
int i3; 		 // valid tentative definition, refers to previous
int i4; 		// valid tentative definition, refers to previous
int i5; 		// 6.2.2 renders undefined, linkage disagreement(gcc,不允許先內部鏈接臨時性定義,再外部鏈接臨時性定義)
extern int i1;  // refers to previous, whose linkage is external
extern int i2;  // refers to previous, whose linkage is internal
extern int i3;  // refers to previous, whose linkage is external
extern int i4;  // refers to previous, whose linkage is external
extern int i5;  // refers to previous, whose linkage is internal
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章