-ansi
是一个过时的开关,请求编译器按照30年前的过时的C标准修订版 ISO/IEC 9899:1990 进行编译,这本质上是ANSI标准 X3.159-1989 "Programming Language C" 的重新命名。为什么过时?因为在ISO发布了C90之后,ISO一直负责C标准化,并且对C90的任何技术勘误都已经被ISO标准化。因此,更适合使用-std=c90
。
没有这个开关,最近的GCC C编译器将符合ISO/IEC 9899:2011或最新的2018修订版中规定的C语言标准。
不幸的是,有些懒惰的编译器供应商认为坚持使用旧的过时标准修订版是可以接受的,而这些标准化文档甚至无法从标准机构获取。
使用该开关有助于确保代码可以在这些过时的编译器中进行编译。
-pedantic
是一个有趣的选项。如果没有 -pedantic
,即使请求了特定的标准,GCC 仍将允许一些不符合 C 标准的扩展。例如考虑下面的程序:
struct test {
int zero_size_array[0];
};
C11草案n1570第6.7.6.2p1节中提到:
除了可选的类型限定符和关键字static之外,[和]可以用来界定一个表达式或*。如果它们界定了一个表达式(指定数组的大小),那么该表达式必须具有整数类型。如果该表达式是一个常量表达式,它的值必须大于零。[...]
C标准要求数组的长度必须大于零;而这段话属于约束条件;标准在5.1.1.3p1节中如下所述:
即使行为也明确规定为未定义或实现定义,符合规范的实现应当以一种实现定义的方式产生至少一条诊断消息,如果预处理翻译单元或翻译单元包含任何语法规则或约束条件的违反。在其他情况下,不需要产生诊断消息。9)
然而,如果您使用gcc -c -std=c90 pedantic_test.c
编译程序,则不会产生警告。
-pedantic
使编译器实际上遵守C标准;因此现在它将生成诊断消息,正如标准所要求的那样:
gcc -c -pedantic -std=c90 pedantic_test.c
pedantic_test.c:2:9: warning: ISO C forbids zero-size array ‘zero_size_array’ [-Wpedantic]
int zero_size_array[0];
^~~~~~~~~~~~~~~
因此,为了实现最大的可移植性,仅仅指定标准修订版是不够的,您还必须使用-pedantic
(或-pedantic-errors
)来确保GCC实际上符合标准的要求。
这个问题的最后一部分是关于在
C++中使用
-ansi
。 ANSI从未标准化C++语言 - 只是从ISO中采用了它,因此这就像说“由法国标准化的英语”一样没有意义。然而,GCC似乎仍然接受它来编译C++,尽管听起来很愚蠢。