2015-11-26 36 views
-2

下面的代碼有變量用於初始化自己,我很難理解變量聲明何時完成,並且即使它們在gcc中編譯,它們中的一些也是非法的。變量聲明的完成點

int main(void) 
{ 
    int a = a; 
    int b = (int) &b; 
    int c = c ? 1 : 0; 
    int d = sizeof(d); 
} 

回答

2

在你的代碼

int a = a; 

是UB,因爲你正在閱讀一個不確定的值。

int b = (int) &b; 

將編譯罰款,因爲該變量已經分配的內存,但它不是由標準的int將能夠容納一個指針的值保證。所以,從技術上講,這也將會發展到UB。

int c = c ? 1 : 0; 

由於與第一個相同的原因,UB是UB。

int d = sizeof(d); 

是好的,因爲在這種情況下,sizeof在編譯時被評估並且該值是一個編譯時間常數。

+0

你可以引述相關的C標準的部分太的一部分嗎? –

+0

如果第二件作品是實施相關的。一般來說,用'(u)intptr_t'來存儲一個指針是一個非常糟糕的主意。 – Olaf

+0

@Olaf有道理!讓我更新那部分。 –

0

a

int a = a; 

定義a評價和初始化之前發生。同樣去與不同之處在於第一和第三將調用未定義的行爲的第二和第四聲明..

int c = c ? 1 : 0; 

問題的情況是變量c被初始化之前使用,並且可以導致未定義的行爲。

1

此概念最好在C++標準(3.3.2點聲明的)中描述的並具有在用於名稱聲明的C標準

1所述的點的相同的含義立即是其 後完整的申報人(第8條)和在其初始化程序(如果有的話), 之前,除了下面指出。

[ Example: 
int x = 12; 
{ int x = x; } 

這裏第二個x初始化與它自己的(不確定的)值。 末端示例]

在代碼示例的顯示,此聲明

int a = a; 

變量a由本身初始化。所以它具有不確定的價值。

本聲明

int b = (int) &b; 

是有效的和可變b具有實現定義的值。

這個聲明

int c = c ? 1 : 0; 

其實相當於第一個聲明。變量c具有不確定的值。

此聲明

int d = sizeof(d); 

是有效的,因爲在操作者sizeof使用的表達是未計算的。

1

查看在C11說明書6.2.1節標識符的作用域。變量的作用域在其聲明完成後開始。對於聲明符的含義見第6.7.6聲明符。請注意,初始化程序(如果存在)位於聲明程序之後,因此聲明的變量位於初始化程序的範圍內。見6.7節的聲明爲聲明的語法中,初始化初始化聲明符定義爲

init-declarator: 
    declarator 
    declarator = initializer