2016-10-03 73 views
0

在C中,在聲明它的同一語句中使用變量是否有效?在同一語句中聲明並使用變量

在這兩種GCC 4.9和3.5鐺下面的程序編譯和運行而不會出現錯誤:

#include "stdio.h" 

int main() { 
    int x = x; 
    printf("%d\n", x); 
} 

在GCC它輸出0和在鐺32767(這是最大的正2字節的整數值)。

爲什麼這不會導致編譯錯誤?這是否適用於任何特定的C規範?其行爲是否明確未定義?

+2

在MSVC中,它輸出「警告C4700:未初始化的本地變量'x'used」。在提出愚蠢的問題之前,請啓用編譯器警告。 –

+1

@WeatherVane:編譯器發出警告的事實不會告訴你它是否有效。 –

+0

MSVC輸出在運行時'-1373317485'嗯,一次,各種值。 –

回答

4
int x = x; 

這是「有效的」,因爲它不違反約束或語法規則,因此不需要編譯時診斷。名稱x在初始化程序中可見,並引用正在聲明的對象。發明的範圍在N1570 6.2.1第7段中定義:

Any other identifier [other than a struct, union, or enum tag, or an enum constant] has scope that begins just after the completion of its declarator.

聲明符在這種情況下是int x

這使得喜歡的事情:

int x = 10, y = x + 1; 

但聲明是未定義行爲,因爲初始化是指尚未初始化的對象。

行爲未定義的顯式聲明在N1570 6.3.2.1第2段中,它描述了左值(指定對象的表達式)到存儲在該對象中的值的「轉換」。

Except when [list of cases that don't apply here], an lvalue that does not have array type is converted to the value stored in the designated object (and is no longer an lvalue); this is called lvalue conversion.
[...]
If the lvalue designates an object of automatic storage duration that could have been declared with the register storage class (never had its address taken), and that object is uninitialized (not declared with an initializer and no assignment to it has been performed prior to use), the behavior is undefined.

有問題的對象是初始值設定項中引用的x。此時,沒有給x賦值,所以表達式具有未定義的行爲。

實際上,如果啓用足夠高的警告級別,您可能會收到編譯時警告。實際行爲威力是一樣的,如果你遺漏了初始化:

int x; 

但不要指望它。

+0

如果代碼是'unsigned char x = x;',它會有所作爲嗎? [C11 6.2.6.2 1] – chux

+0

這一切都是正確的,但它有點回避了這個問題。您可以使用自引用初始化來構造循環列表,例如:'struct node {int value; struct node * next,* prev;} x =(struct node){argc,&x,&x};'。據我所知,這是合法的,併產生預期的結果。 – rici

+0

@chux:我不這麼認爲。 6.3.2.1p2仍然適用。 –

1
int x = x; 

導致未定義的行爲。不要指望任何可預測的行爲。

+0

任何參考標準,將顯示此?我直覺地認同你,這是未定義的行爲。不過,擁有權威來源將是一件好事。 – Sjlver

+1

由於值是不確定的,因此它是右值轉換的左值。 –

+0

@Sjlver,我找不到比dasblinkenlight引用的更多的東西。 –

1

鏘也提醒一下:

$ clang -c -Wall ub_or_not_ub.c 
ub_or_not_ub.c:4:11: warning: variable 'x' is uninitialized when used within its own initialization [-Wuninitialized] 
    int x = x; 
     ~ ^

所以我想這是不確定的行爲。

+1

這是一個很好的猜測,但它仍然只是一個猜測。 –

2

根據該語言規範

6.7.8.10 If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate.

此外,它說

6.7.8.11 The initializer for a scalar shall be a single expression, optionally enclosed in braces. The initial value of the object is that of the expression (after conversion).

因此,初始化表達式(x到的=右側)的值是不確定,所以我們正在處理未定義的行爲,因爲初始化器從變量x中讀取具有不確定性的值。

各種編譯器提供警告設置以捕獲這些情況。

+0

您錯過了導致未定義行爲的部分。 –

+0

@DavidSchwartz - 不會「它的價值是不確定的。」等於UB? – KevinDTimm

+0

@KevinDTimm不是馬上。有一個不確定的值是不是UB,只要你沒有在分配之前閱讀它。這就是爲什麼我編輯答案來澄清大衛的觀點。 – dasblinkenlight

相關問題