-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 禁止可变长度数组 '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

4 回答 4

4

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

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

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

于 2012-12-24T19:12:50.597 回答
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 不同。

于 2012-12-24T19:13:39.567 回答
2

可变长度数组仅从 C99 开始受支持,并且它们不能是全局的:

C11,数组声明器,6.7.6.2:

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

于 2012-12-24T19:06:30.887 回答
1

是的,并且?

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

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

于 2012-12-24T19:04:01.310 回答