我在编码中一直使用它。
-ansi
标志等同于 -std=c89
。如前所述,它关闭了 GCC 的一些扩展。添加 -pedantic
会关闭更多扩展并生成更多警告。例如,如果您的字符串文字长度超过 509 个字符,则 -pedantic
会发出警告,因为它超出了 C89 标准要求的最小限制。也就是说,每个 C89 编译器都必须接受长度为 509 的字符串;它们被允许接受更长的时间,但是如果你是迂腐的,使用更长的字符串是不可移植的,即使编译器被允许接受更长的字符串,并且在没有迂腐警告的情况下,GCC 也会接受它们。
如果可能的话,GCC 编译器总是试图编译你的程序。但是,在某些情况下,C 和 C++ 标准指定禁止某些扩展。遇到这些扩展时,符合标准的编译器(例如 GCC 或 g++)必须发出诊断。
例如,GCC 编译器的 -pedantic 选项会导致 GCC 在这种情况下发出警告。使用更严格的 -pedantic-errors 选项会将此类诊断警告转换为将导致编译在此类点失败的错误。只有那些需要由符合标准的编译器标记的非 ISO 结构才会生成警告或错误。
-pedantic-errors
与 -Werror=pedantic
不同。他们执行不同的检查。
<-ansi
是一个过时的开关,它要求编译器根据已有 30 年历史的过时的 C 标准修订版、ISO/IEC 9899:1990 进行编译,这本质上是对ANSI标准X3.159-1989“编程语言C的更名。为什么过时了?因为C90由ISO发布之后,ISO一直负责C的标准化,任何< em>C90 的技术勘误已被 ISO 标准化,因此更适合使用 -std=c90
。
如果没有此开关,最新的 GCC C 编译器将符合 ISO/IEC 9899:2011 或最新的 2018 修订版中标准化的 C 语言。
不幸的是,有一些懒惰的编译器供应商认为坚持使用较旧的过时标准修订版是可以接受的,标准机构甚至没有标准化文档。
使用该开关有助于确保代码应该在这些过时的编译器中编译。
-pedantic
很有趣。在没有 -pedantic
的情况下,即使请求了特定的标准,GCC 仍将允许一些 C 标准中不可接受的扩展。例如考虑程序
struct test {
int zero_size_array[0];
};
C11 draft n1570 paragraph 6.7.6.2p1 says:
除了可选的类型限定符和关键字 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 确实符合标准的规定。
问题的最后一部分是关于将 -ansi
与 C++ 一起使用。 ANSI 从未对 C++ 语言进行标准化 - 仅从 ISO 中采用它,因此这与说“法国标准化的英语”一样有意义。然而 GCC 似乎仍然接受它用于 C++,这听起来很愚蠢。
-std=c11 -Wall -Wextra -Wpedantic -Wconversion
进行编译。
-std=c++20
。
如果您的代码需要可移植,那么您可以测试它是否可以在没有任何 GCC 扩展或其他非标准功能的情况下进行编译。如果您的代码使用 -pedantic -ansi
编译,那么理论上它应该可以使用任何其他 ANSI 标准编译器编译。
-pedantic
不会关闭所有扩展,它会留下一堆双下划线的东西。因此,更准确的说法是,如果您的代码使用 -pedantic -ansi
进行编译,并且看起来似乎可以在其他实现上编译,那么它就会编译。
如果您正在编写您设想将在各种平台上使用许多不同编译器编译的代码,那么您自己使用这些标志将有助于确保您不会生成仅在 GCC 下编译的代码。
其他人已经充分回答了。我只想添加一些频繁扩展的示例:
main
函数返回 void
。这不是由标准定义的,这意味着它只能在某些编译器(包括 GCC)上工作,而不能在其他编译器上工作。顺便说一下,int main()
和 int main(int, char**)
是标准定义的两个签名。
另一个流行的扩展是能够在其他函数中声明和定义函数:
void f()
{
void g()
{
// ...
}
// ...
g();
// ...
}
这是非标准的。如果您想要这种行为,请查看 C++11 lambdas
Pedantic 使得 GCC 编译器拒绝所有 GNU C 扩展,而不仅仅是那些使其与 ANSI 兼容的扩展。
-std=c89 -pedantic
确实意味着您可以更轻松地在其他平台上的不同编译器之间移动。一旦您开始使用<windows.h>
,与其他系统的兼容性就会出现问题。-pedantic
,但是当我重新启用它时,我的大部分代码仍然可以正常编译(一个没有明确使用__int128
类型的程序, 是 迂腐不正确)。我认为当 GCC 对-pedantic
过于嘈杂(我喜欢)时,存在一个中间阶段。我刚刚测试了大约 300 个源文件——一些库代码、一些命令、一些 SO 测试程序——而且只有一个预期的问题。目前在 Mac OS X 10.9.2 上使用 GCC 4.8.2。