2015-10-16 69 views
2

定義考慮代碼:宣言VS用C

int main(void) 
{ 
    int a; 
} 

據我所知,int a;是一個定義,因爲它會導致存儲被保留。援引C標準(N1570委員會草案 - 2011年4月12日):

6.7/5語義 甲聲明指定一組標識符的解釋和屬性。的識別符的定義是該標識符的聲明:

- 爲一個對象,使存儲到該對象保留;

...

問題來了:編譯器可以優化掉的存儲,因爲我們沒有使用變量。然後int a;一個聲明呢?而如果我們在一個main(void)printf("%p", &a)做 - 當然現在的編譯器分配存儲空間,所以是聲明/定義的概念依賴於你是否以後使用標識符或沒有?

+0

的定義是總的定義,即使不使用(並且甚至當編譯器實際上不發射碼或保留空間爲它)。 –

+0

@JoachimPileborg這個標準有點含糊不清,它肯定地說:*導致存儲保留... *。然後貫穿整個標準,該術語可互換使用,例如,他們調用'int * p;'a *聲明*。整個討論開始[here](http://stackoverflow.com/a/33159989/3093378) – vsoftco

+0

[定義和聲明之間有什麼區別?](http://stackoverflow.com/questions/ 1410563 /定義和聲明之間的區別是什麼) –

回答

5

從6.7/5引用的文本實際上是爲了解釋周圍比你做了什麼其他的方式:文字是說,定義導致存儲進行分配。

指定int a;是定義的文本在別處。

C是根據抽象機器來定義的。抽象機器中分配了存儲空間。是否在您的PC上分配任何內存是不相關的。

+0

讓我感到困惑的是他們指的是'const int * ptr_to_constant;'作爲*聲明*,見6.7.6.1/3(鏈接文檔的第130頁)。從技術上講,這是正確的,因爲一個定義也可以是一個聲明... – vsoftco

+0

@vsoftco所有的定義都是聲明,所以術語是正確的(儘管也許是誤導) –

+0

是的,這可能是怎麼回事。但抽象機器當然是正確的思考方式。但是'int f(); main(){} int f(){return 0;}不是'int f(){return 0;}'只有一個定義嗎?或者你在談論變量? – vsoftco

2

然後是int a;一個聲明呢?

是的。

事實上,每一個定義也是聲明。一個變量只能有一個定義,但可以有多個聲明。

2
int a; 

這是一個定義 分配有可變a

extern int a; 

這是聲明的記憶。 內存未分配,因爲未定義。

一旦變量被定義,你可以使用它的地址,這是完全合法的。

0

聲明引入了一個標識符並描述了它的類型,無論是類型,對象還是函數。聲明是編譯器需要接受對該標識符的引用。這些是聲明:

extern int bar; 
extern int g(int, int); 

定義實際實例化/實現此標識符。這是鏈接器爲了將引用鏈接到這些實體所需要的。這些是對應於上述的聲明定義:

int bar; 
int g(int lhs, int rhs) {return lhs*rhs;}