2012-12-24 61 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++没有可变长度数组。