我正在阅读C Primer Plus中的VLA,本书严格地说,将C语言引入C语言的C引入。每当我尝试在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模式,这怎么可能合法?
答案 0 :(得分:9)
这本书是正确的,自 C99 以来一直支持可变长度数组,如果你使用以下选项构建:
gcc -std = c89 -pedantic
您将收到警告:
警告:ISO C90禁止变长数组'array'[-Wvla]
如果您希望这是一个错误,可以使用-pedantic-errors
。 gcc
在c99
之前c99
支持此extension,您可以在gcc
模式下明确构建,您将看到没有错误:
gcc -std = c99 -pedantic
Language Standards Supported by GCC页面详细介绍了哪个标准{{1}}支持C,并声明:
默认情况下,GCC提供了一些C语言扩展,在极少数情况下会与C标准冲突
答案 1 :(得分: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’
答案 2 :(得分:3)
“如果我不是C99模式,这怎么可能合法?”
允许编译器具有严格符合C标准的模式。
实际上,C标准只是一个规范。没有法律规定你必须遵守它,并且没有法律规定编译器开发人员必须遵守它。
因此,允许编译器在语言上定义自己的变体,并使用自己的规范甚至是某些第三方编写的规范进行编译。
不仅如此,C标准还定义了可扩展的语言。在保持符合C标准的同时,允许实现许多行为。 C标准甚至指定一致性程序是符合实现可接受的任何程序。这意味着使用编译器扩展的程序仍然是符合C的程序(在没有任何其他问题的情况下)。 (但是,它不是严格符合的程序;那些是不使用扩展的程序。)