C90中是否真的不允许使用可变长度数组?

5

我正在阅读C Primer Plus中关于VLAs的内容。该书严格指出,引入VLAs到C语言是从C99标准开始的。每当我试图在for循环头中声明一个循环控制变量时,gcc会提示我只有在C99模式下才允许这样做。但是,以下测试代码可以编译并工作(尽管它打印垃圾变量,这是可以预料的,因为数组元素没有被初始化)。

#include <stdio.h>

int main(){
    int x; 
    int i = 9; 
    int array[i]; 

    for(x = 0; x < i; x++)
        printf("%d\n", array[x]);

    return 0; 
}

如果我没有处于C99模式,这怎么可能是合法的呢?

你使用的编译器是什么?在编译时你传递了哪些参数? - Timothy Jones
你可能会收到警告:ISO C90禁止变长数组“array”。 - Dayal rai
这个问题虽然不是严格的重复,但似乎与此相关。 - Timothy Jones
http://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html - Michael Burr
3个回答

9
这本书是正确的,自从C99以来就支持变长数组。如果你使用以下选项进行构建:

gcc -std=c89 -pedantic

你将收到一个警告:

警告:ISO C90禁止变长数组“array”[-Wvla]

如果你想让它成为一个错误,可以使用-pedantic-errors。在c99之前,gcc支持此扩展,你可以显式地以c99模式构建,这样就不会出现错误:

gcc -std=c99 -pedantic

gcc支持的语言标准页面详细介绍了gcc支持的C标准,它指出:

默认情况下,GCC提供一些扩展C语言的功能,但在极少数情况下与C标准冲突。


8

如果我不在C99模式下,这怎么可能是合法的?

它不合法。然而,GCC允许它作为一种编译器扩展。

你可以通过传递-pedantic标志来强制GCC对此进行严格处理:

$ gcc -std=c89 -pedantic main.c
main.c: In function ‘main’:
main.c:6: warning: ISO C90 forbids variable-size array ‘array’

3
这里的含义很明显:**总是使用-pedantic**,此外还要使用-Wall -Wextra -Werror,除非有充分的理由(例如会破坏现有遗留代码)不使用。 - Konrad Rudolph
-pedantic 对于未使用的参数可能会非常烦人。Clang 还有一个 -Weverything 标志,这可能会变得非常痛苦和快速。 - Carl Norum
1
使用-pedantic-errors。并注释掉未使用的参数。或者不要使用未使用的参数...哦等等 :P - rubenvb
@KonradRudolph,这并不总是可能的。有时你必须实现现有的API。 - Carl Norum
@CarlNorum:就我个人而言,如果你从头开始启动一个项目,我并不认为clang的“-Weverything”会让人感到痛苦:makefile和“-Wno-*”使得全局或每个文件级别上排除特定警告变得容易,并且正如Konrad所提到的,对于第三方头文件,还有“-isystem”。 - Christoph
显示剩余2条评论

3

“如果我不是处于C99模式,这怎么可能是合法的?”

编译器可以有其他严格遵循C标准之外的模式。

实际上,C标准只是一个规范。没有法律规定您必须符合它,也没有法律规定编译器开发人员必须符合它。

因此,编译器可以定义自己语言的变化,并使用自己的规范或甚至第三方编写的规范进行编译。

更重要的是,C标准定义语言是可扩展的。许多行为是允许被实现定义,同时仍符合C标准。 C标准甚至规定一个符合的程序是指任何符合实现接受的程序。 这意味着使用编译器扩展的程序仍然是符合C的程序(在没有其他问题的情况下)。 (但是,它不是一个严格符合的程序;那些是不使用扩展的程序。)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接