不寻常的行为

时间:2012-12-24 18:58:58

标签: c++ c

为什么此代码无法编译

#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禁止变长数组'a'[-Wvla]

但是,如果我尝试使用g ++ 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

请详细说明发生了什么?

4 个答案:

答案 0 :(得分:4)

在C中,只有具有自动存储持续时间的数组对象可以是可变长度数组。在文件范围内声明的对象不能具有自动存储持续时间。

在第二个代码示例中,c89 / c90没有可变长度数组,您必须使用c99编译器才能使用该功能。如果您使用的是gcc,则可以使用选项-std=c99选择c99。或者您可以使用最新版本的c:c11。

C ++没有可变长度数组。

答案 1 :(得分:4)

在C语言中(与C ++不同)const声明不会产生常量表达式,即在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中的 const并不代表常量。这意味着“只读”。

注意变量长度数组仅在C99中成为C标准的一部分,之前标准不允许它们,尽管大多数编译器允许它们作为扩展。


第一个代码片段无法编译,因为数组下标需要是常量,而不是。此外,不能在全局范围内声明可变长度数组。

第二个代码片段无法编译,因为变量长度数组不是c99之前的标准的一部分。

第三个片段编译,因为const声明在C ++中产生与C不同的常量表达式。

答案 2 :(得分:2)

自C99以来仅支持可变长度数组,它们不能是全局的:

C11,数组声明符,6.7.6.2:

  

如果标识符被声明为具有可变修改类型,则为   应为普通标识符(如6.2.3中所定义),否则   链接,并具有块范围或函数原型范围。如果   标识符声明为具有静态或线程的对象   存储持续时间,它不应具有可变长度的数组类型。

答案 3 :(得分:1)

是的,还有?

不同代的C和C ++对于可用于调整数组大小的内容有不同的规则。在第一种情况下,您将编译为经典ANSI(C89 / 90)。

C ++允许(常量)用作数组大小,C99也是如此。请注意,“原始”C ++ ANSI标准比1990年更新,因此它在C99标准中添加了许多内容。