在GCC / G ++编译器中使用-pedantic的目的是什么?

这个笔记说:

-ansi :告诉编译器实现ANSI语言选项。 这closures了与ANSI标准不兼容的GCC的某些“特征”。

-pedantic :与-ansi一起使用,这告诉编译器严格遵守ANSI标准,拒绝任何不合规的代码。

首先要做的事情

  • GCC / G ++编译器的-pedantic-ansi选项的目的是什么(我无法理解上面的描述)?
  • 任何人都可以告诉我使用这两个选项的正确的情况吗?
  • 我应该什么时候使用它们?
  • 他们重要吗?

GCC编译器总是试图编译你的程序,如果这是可能的话。 但是,在某些情况下,C和C ++标准指定禁止某些扩展。 符合编译器(如gcc或g ++)必须在遇到这些扩展时发出诊断。 例如,gcc编译器的-pedantic选项会导致gcc在这种情况下发出警告。 使用更严格-pedantic-errors选项可将此类诊断警告转换为会导致编译失败的错误。 只有那些需要被一致性编译器标记的非ISO结构才会产生警告或错误。

我在编码中一直使用它。

-ansi标志相当于-std=c89 。 如上所述,它closures了GCC的一些扩展。 添加-pedanticclosures更多扩展并生成更多警告。 例如,如果您的string文字长度超过509个字符,则-pedantic警告,因为它超过了C89标准所要求的最小限制。 也就是说,每个C89编译器都必须接受长度为509的string; 他们被允许接受更长的时间,但如果你是迂腐的话,即使编译器被允许接受更长的string,并且没有迂腐的警告,GCC也会接受它们,使用更长的string是不可移植的。

基本上,这会使你的代码在其他也实现ANSI标准的编译器下编译起来更容易,而且如果你在其他操作系统/平台下使用库/ api调用时要小心。

第一个,closures海湾合作委员会的具体特点。 (-ansi)第二个,会抱怨任何不符合标准的东西(不仅仅是GCC的具体特征,而且也是你的构造)(-pedantic)。

如果你的代码需要可移植,那么你可以testing它编译没有任何gcc扩展或其他非标准function。 如果你的代码用-pedantic -ansi编译,那么在理论上它应该用任何其他ANSI标准编译器编译OK。

如果您正在编写代码,您将在各种各样的平台上编译,并使用多种不同的编译器,那么自己使用这些标记将有助于确保您不会生成只能在GCC下编译的代码。

-ansi是一个过时的开关,它要求编译器根据C标准ISO / IEC 9899:1990)的27年过时修订进行编译,这本质上是ANSI标准X3.159-1989“编程语言C ,为什么过时?因为ISO发布C90之后,ISO已经负责C标准化工作,而且C90的任何技术勘误已经由ISO公布,因此更容易使用-std=c90

如果没有这个开关,最近的GCC C编译器将符合ISO / IEC 9899:2011标准化的C语言。 不幸的是,有一些懒惰的编译器供应商认为坚持编译器标准修订版是可以接受的,因为标准版文档甚至不能从标准机构获得。 使用开关确保代码将在这些过时的编译器中编译。


这个-pedantic是一个有趣的。 即使在需要特定的标准的情况下,GCC仍然允许一些在C标准中不能接受的扩展。 考虑一下例如程序

 struct test { int zero_size_array[0]; }; 

C11草案n1570段落6.7.6.2p1说 :

除了可选的types限定符和关键字static之外,[和]可以分隔expression式或*。 如果它们分隔一个expression式(它指定了一个数组的大小),expression式应该有一个整数types。 如果expression式是一个常量expression式, 则其值应大于零。 […]

C标准要求数组长度大于零; 而这一段是有约束的 ; 该标准说明如下5.1.1.3p1 :

如果预处理翻译单元或翻译单元包含违反任何语法规则或约束的情况,即使该行为也被明确指定为未定义或实现定义的,则一致性实现应产生至less一个诊断消息(以实现定义的方式标识)定义。 在其他情况下不需要产生诊断信息。9)

但是,如果使用gcc -c -std=c90 pedantic_test.c编译程序gcc -c -std=c90 pedantic_test.c ,则不会产生警告。

编译器实际上符合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 ++,听起来很愚蠢。

其他人已经充分回答。 我只想添加一些频繁扩展的例子:

main函数返回void 。 这不是由标准定义的,这意味着它只能在一些编译器(包括GCC)上工作,而不能在其他编译器上工作。 顺便说一下, int main()int main(int, char**)是标准定义的两个签名。

另一个受欢迎的扩展是能够声明和定义其他函数内的函数:

 void f() { void g() { // ... } // ... g(); // ... } 

这是非标准的。 如果你想要这种行为,请检查C ++ 11 lambdaexpression式

Pedantic使得gcc编译器拒绝所有的GNU C扩展,而不仅仅是ANSI兼容的扩展。