是否存在GCC选项可将"int i[]"当作"int *i"处理?
GCC选项允许非标准空方括号写法?
问题描述
在移植大型代码库时发现,旧版C编译器对空方括号的限制更为宽松。现询问是否存在GCC选项,可允许此类写法(即便不符合标准)?示例代码如下:
void foo() { extern int i[]; /* gcc -c foo.c gives "incomplete type" error */ int x; i=&x; }补充说明:此前示例代码存在错误,经AnT指出i并非左值,核实旧编译器后发现该代码同样无法编译,特此致歉。
回答
首先得澄清一下:你给出的示例代码里的编译错误,本质和空方括号的宽松规则没太大关系。extern int i[]声明的是一个不完整类型的数组,而在C语言里,数组表达式在几乎所有语境下都会自动转换成指向首元素的指针,这意味着i在这里是个右值指针,根本没法被赋值——不管是旧编译器还是GCC,这种写法都不合法,这是C类型系统的基本规则,不是编译器宽松度的问题。
回到你核心的需求:如果代码库里存在其他旧编译器允许但标准C不支持的空方括号用法(比如特定场景下省略数组大小、非标准的数组声明方式等),GCC确实有几个选项可以帮你兼容这类旧行为:
-std=gnu89:切换到GNU扩展的C89模式,这是最接近旧编译器行为的标准模式。它对数组类型的处理会比现代C标准宽松很多,比如允许一些在C99及以后被禁止的空方括号声明方式。-fms-extensions:启用微软C语言扩展,其中包含不少对数组声明的宽松规则,比如支持函数参数里的非标准空方括号写法,或者全局数组初始化时的某些灵活处理。-Wno-incomplete-type:如果你的主要困扰是GCC抛出的“incomplete type”错误(就像示例里的提示),这个选项可以禁用这类警告/错误。但要注意,这只是抑制报错,并没有改变代码的语义,可能会引入未定义行为,建议只在临时移植阶段使用,后续还是要逐步修正代码。
另外,如果你的代码里存在类似示例里的“给数组赋值”的写法,本质上是把数组当成指针用了——这种情况下,最稳妥的方式不是找编译器选项,而是直接修改代码:把extern int i[]改成extern int *i,这样i=&x;的赋值就完全符合标准C的规则了,不管哪个编译器都能正常编译。
内容的提问来源于stack exchange,提问作者in foq
相关产品推荐
相关产品推荐

