不寻常的行为

Unusual behaviour

本文关键字:不寻常      更新时间:2023-10-16

为什么这段代码不能编译

#include <stdio.h>
int x=5;
int a[x];
int main()
{
     a[0]=5;
     printf("%dn",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("%dn",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("%dn",a[0]);
    return 0;
}

我使用的是gcc版本4.7.0

请详细解释一下发生了什么事

在C中(与c++不同),const声明不产生常量表达式,即在C中,你不能在非vla数组声明中使用const int对象作为数组大小。

,

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

在c++中有效,但在C中无效。

#define MAX_FOOS 10
int foos[MAX_FOOS];

注意:
const在c语言中并不意味着常量。

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


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

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

第三段代码可以编译,因为c++中const声明产生的常量表达式与C不同。

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

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

c++没有可变长度数组

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

C11、数组声明符,6.7.6.2:

如果一个标识符被声明为具有可变修改的类型,则该标识符将被调用应为普通标识符(定义见6.2.3),没有链接,并且具有块作用域或函数原型作用域。如果标识符被声明为静态或线程对象

存储期限,它不能是可变长度数组类型。

是,而?

对于数组的大小,不同的C和c++语言有不同的规则。在第一种情况下,您正在编译到经典的ANSI (C89/90)。

c++允许使用(常量)作为数组大小,C99也是如此。请注意,"原始的"c++ ANSI标准比1990年更新,因此它在C99标准中添加了许多东西。