为什么此代码无法编译
#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
请详细说明发生了什么?
答案 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标准中添加了许多内容。