2012-12-24 96 views
-1

爲什麼這個代碼不編譯不尋常的行爲

#include <stdio.h> 
int x=5; 
int a[x]; 
int main() 
{ 
    a[0]=5; 
    printf("%d\n",a[0]); 
    return 0; 
} 

當編譯GCC FILENAME.C -Wall -ansi -pedantic它會產生一個錯誤

錯誤: 'A' 的文件,各種變型範圍

但是這個代碼編譯,雖然提出警告,但給正確的輸出:

#include <stdio.h> 
int main() 
{ 
    int x=5; 
    int a[x]; 
    a[0]=5; 
    printf("%d\n",a[0]); 
    return 0; 
} 

警告:ISO C90禁止可變長度數組 '一個'[-Wvla]

然而,如果我嘗試編譯此使用克++ FILENAME.C -Wall -ansi -pedantic它產生沒有警告並給出正確的輸出也

#include <stdio.h> 
const int x=5; 
int a[x]; 
int main() 
{ 
    a[0]=5; 
    printf("%d\n",a[0]); 
    return 0; 
} 

我使用gcc版本4.7.0

請詳細解釋一下發生了什麼?

+5

的'const'使所有的差異?問題基本上是「爲什麼不正確的代碼不能編譯,而正確的代碼呢?」。 –

+0

研究您正在編碼的語言標準的確切參考。 http://en.wikipedia.org/wiki/C_programming_language http://en.wikipedia.org/wiki/C99 http://en.wikipedia.org/wiki/C%2B%2B http://en.wikipedia .org/wiki/C%2B%2B11並將'-Wall'傳遞給GCC編譯器 –

+0

@LuchianGrigore那麼答案是什麼? – Snehasish

回答

4

在C語言中(與C++不同),常量聲明不會生成常量表達式,即在C語言中,您不能在非VLA數組聲明中使用const int對象作爲數組大小。

所以,

const int max_foos = 10; 
int foos[max_foos]; 

在C++中有效,但在C.無效同樣的C代碼將是:

#define MAX_FOOS 10 
int foos[MAX_FOOS]; 

需要注意的是:
常量在C不等於常數。它的意思是「只讀」。

注意變長數組只是在C99之前成爲了C標準的一部分,在此之前,雖然大多數編譯器都允許它們作爲擴展,但標準不允許它們。


第一個代碼片段不會編譯,因爲數組下標需要是常量而不是它。而且,變長數組不能在全局範圍內聲明。

第二個代碼片段不能編譯,因爲可變長度數組在c99之前不是標準的一部分。

第三片斷編譯因爲const聲明產生用C常量表達式++不像C.

1

是的,?

不同世代的C和C++對於您可以用來調整數組的大小有不同的規則。在第一種情況下,您正在編譯爲經典ANSI(C89/90)。

與C99一樣,C++允許(常量)用作數組大小。請注意,「原始」C++ ANSI標準比1990年更新,所以它在C99標準中增加了很多東西。

2

可變長度數組,因爲C99僅支持,他們不能爲全球:

C11,組聲明,6.7.6.2:

If an identifier is declared as having a variably modified type, it shall be an ordinary identifier (as defined in 6.2.3), have no linkage, and have either block scope or function prototype scope. If an identifier is declared to be an object with static or thread storage duration, it shall not have a variable length array type.

+0

downvote的原因是什麼? –

4

在C僅陣列自動存儲對象持續時間可以是可變長度數組。在文件範圍聲明的對象不能有自動存儲持續時間。

在第二個代碼示例中,c89/c90沒有可變長度數組,您必須使用c99編譯器才能使用該功能。如果您使用的是gcc,則可以通過選項-std=c99選擇c99。或者你可以使用c:c11的最後一個版本。

C++沒有可變長度數組。