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

hua*_*n68 127 c c++ gcc g++

这张便条说:

-ansi:告诉编译器实现ANSI语言选项.这会关闭GCC的某些与ANSI标准不兼容的"功能".

-pedantic:与-ansi此结合使用,这告诉编译器严格遵守ANSI标准,拒绝任何不符合的代码.

首先要做的事情:

  • GCC/G ++编译器的选项-pedantic-ansi选项的目的是什么(我无法理解上面的描述)?
  • 谁能告诉我使用这两个选项的合适情况?
  • 我应该什么时候使用它们?
  • 它们重要吗?

Jon*_*ler 97

我在编码中一直使用它.

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

  • @ huahsin68:好吧,或多或少.MSVC与大多数其他编译器的编译器完全不同,更适合其特定的生态系统,而且不能在其外部使用.它以自己的方式做了很多事情 - 这与标准不同.然而,如果你使用标准的标题等等,那么MSVC和GCC非常相似.但是,使用`-std = c89 -pedantic`意味着您可以更轻松地在其他平台上的不同编译器之间移动.一旦开始使用`<windows.h>`,与其他系统的兼容性就会出现问题. (4认同)
  • @slf:因为像其他所有供应商一样(尽管GNU不会出售他们的编译器以换取现金),他们希望您使用他们的专有功能吗?或者,更一般地说,因为他们认为扩展有用,并认为默认情况下应该启用它们. (2认同)
  • 不管它的价值如何,以及 [JFTR](http://acronymfinder.com/JFTR.html),我基本上已经停止使用 `-pedantic`,但是当我重新启用它时,我的大部分代码仍然可以编译(一个没有明确使用 `__int128` 类型的程序,这是 _are_ 迂腐不正确的)。我认为当 GCC 使用“-pedantic”太吵(我喜欢)时,有一个干预阶段。我刚刚测试了大约 300 个源文件——一些库代码、一些命令、一些 SO 测试程序——并且只有一个预期的问题。目前在 Mac OS X 10.9.2 上使用 GCC 4.8.2。 (2认同)

Waz*_*ery 76

如果可能的话,GCC编译器总是尝试编译您的程序.但是,在某些情况下,C和C++标准指定禁止某些扩展.当遇到这些扩展时,符合gcc或g ++等编译器必须发出诊断信息.例如,gcc编译器的-pedantic选项会导致gcc在这种情况下发出警告.使用更严格的 -pedantic-errors选项可将此类诊断警告转换为错误,从而导致编译在这些点上失败.只有那些需要由符合标准的编译器标记的非ISO构造才会生成警告或错误.

  • ISO C和C++标准仅"禁止扩展",因为扩展不得改变任何符合程序的行为.编译器不会强制拒绝任何使用扩展的程序. (3认同)

Ant*_*ala 20

-ansi是请求编译器根据27岁的编译过时的开关的C标准过时的修订,ISO/IEC 9899:1990,这基本上是ANSI标准的品牌重塑X3.159-1989"C语言编程.为什么过时了吗?C90是由ISO出版后因为,ISO一直负责的C标准化的,任何技术勘误到C90已经由ISO出版.因此,它是更容易使用-std=c90.

如果没有这个开关,最近的GCC C编译器将符合ISO/IEC 9899:2011标准化的C语言.

不幸的是,有一些懒惰的编译器供应商认为坚持使用较旧的过时标准版本是可以接受的,标准化文档甚至不能从标准机构获得.

使用该开关有助于确保代码应该在这些过时的编译器中编译.


-pedantic是一个有趣的.如果没有-pedantic,即使要求特定标准,GCC仍将允许一些C标准中不可接受的扩展.考虑例如程序

struct test {
    int zero_size_array[0];
};
Run Code Online (Sandbox Code Playgroud)

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];
         ^~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)

因此,为了最大程度的可移植性,指定标准修订版是不够的,您还必须使用-pedantic(或-pedantic-errors)确保GCC实际上符合标准的字母.


这个问题的最后一部分是有关使用-ansiC++.ANSI从未标准化C++语言 - 仅从ISO中采用它,因此这与"法国标准化的英语"一样有意义.然而,GCC似乎仍然接受它用于C++,听起来很愚蠢.

  • 请注意,语言标准已有进一步的修订。今天,我通常使用-std = c11 -Wall -Wextra -Wpedantic -Wconversion进行编译。 (3认同)

Fra*_*oto 14

基本上,它将使您的代码更容易在其他编译器下编译,这些编译器也实现ANSI标准,并且,如果您在其他操作系统/平台下小心使用哪些库/ api调用.

第一个,关闭GCC的特定功能.(-ansi)第二个,会抱怨任何不符合标准的东西(不仅是GCC的具体特征,而且也是你的构造.)(-pedantic).


Pau*_*l R 6

如果您的代码需要是可移植的,那么您可以测试它编译时没有任何gcc扩展或其他非标准功能.如果您的代码-pedantic -ansi在理论上编译,那么它应该与任何其他ANSI标准编译器一起编译.

  • `-pedantic`并没有关闭所有扩展,它留下了一堆双下划线的东西.因此,如果您的代码使用`-pedantic -ansi`进行编译,并且它看起来似乎可以在其他实现上编译,那么可能会更准确,那么它将进行编译. (4认同)
  • 你提到双下划线的东西,听起来很有趣.你到底在指的是什么? (3认同)
  • 一个例子是 gcc 的“__asm__()”内联汇编代码,它对 gcc 很好,但双下划线的东西可能不适用于 Windows 编译器,即使该编译器确实符合标准。 (3认同)

Dam*_*ver 5

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

  • 在某些版本的 GCC 下! (2认同)