我想说明数组不能用C89或C90中的长度变量来定义。
我在Windows上使用的GCC来自TDM GCC:
C:\TDM-GCC-64\bin> .\gcc.exe --version
gcc.exe (tdm64-1) 10.3.0
我的编译选项包括:gcc.exe -Wall -g -ansi -save-temps -c
我试探着:
int main()
{
int i;
int tab[i];
tab[0] = 10;
return 0;
}
但它编译得很好:
gcc.exe -Wall -g -ansi -save-temps -c main.c -o main.o
gcc.exe -o Sandbox.exe main.o
main.c:6:9: warning: variable 'tab' set but not used [-Wunused-but-set-variable]
6 | int tab[i];
| ^~~
main.c:6:5: warning: 'i' is used uninitialized in this function [-Wuninitialized]
6 | int tab[i];
| ^~~
Output file is bin\Debug\Sandbox.exe with size 196.89 KB
然后道:
int test(int i)
{
int tab[i];
tab[0] = 10;
return 0;
}
也编译:
main.c: In function 'test':
main.c:5:9: warning: variable 'tab' set but not used [-Wunused-but-set-variable]
5 | int tab[i];
| ^~~
Output file is bin\Debug\Sandbox.exe with size 196.90 KB
或者:
int main()
{
volatile int i;
int tab[i];
tab[0] = 10;
return 0;
}
只有这一点是不编译的:
第一个
我错过了什么?谢谢!
2条答案
按热度按时间v09wglhw1#
变长数组是GCC的一个扩展,它与标准是“兼容的”。如果你想严格遵守标准,也就是说,你想在使用扩展时得到一个消息,添加
-pedantic
选项(和-pedantic-errors
表示错误)。美国政府采购委员会文件:https://gcc.gnu.org/onlinedocs/gcc-12.2.0/gcc/Variable-Length.html#Variable-Length,https://gcc.gnu.org/onlinedocs/gcc-12.2.0/gcc/Warning-Options.html#Warning-Options。
j2cgzkjk2#
gcc默认的标准符合性很差,它默认为lax C一致性+ GNU扩展,相当于
-std=gnu89
(当前版本默认为-std=gnu17
)。当你输入
-ansi
时,它并不意味着一致模式,而是和-std=c89
一样的东西,“lax C89模式”。这个编译器选项可能会禁用一些GNU扩展......也许......同时保留其他的。-std=c89
和-std=gnu89
之间的区别和gcc的其他部分一样,被记录的很少。我们可以read the unfriendly manual,它说:例如,-std=c90会关闭GCC中与ISO C90不兼容的某些功能,如asm和typeof关键字,但不会关闭在ISO C90中没有意义的其他GNU扩展
gcc甚至在C99之前就支持可变长度数组作为扩展,所以关闭GNU选项应该会禁用它们,但事实并非如此......据我所知,没有官方文档说明
-std=c89
关闭了哪些特性,或者至少我找不到。需要注意的是,
-std=c89
/-ansi
本身并不能将gcc推入一致模式!要做到这一点,您需要执行-std=c89 -pedantic
或-std=c89 -pedantic-errors
。之后,您将得到如下诊断:错误:ISO C90禁止使用可变长度数组'tab'
当结合使用这两个选项进行编译时,gcc可能是所有编译器中最符合标准的。