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

时间:2010-05-18 07:07:52

标签: c++ c gcc g++

This note说:

  

-ansi:告诉编译器实现ANSI语言选项。这转变   关闭海湾合作委员会的某些“特征”   与ANSI不兼容   标准。

     

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

首先要做的事情:

  • GCC / G ++编译器的-pedantic-ansi选项的用途是什么(我无法理解上述说明)?
  • 有人能告诉我使用这两种选择的正确情况吗?
  • 我什么时候应该使用它们?
  • 他们重要吗?

8 个答案:

答案 0 :(得分:97)

我在编码中一直使用它。

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

答案 1 :(得分:73)

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

答案 2 :(得分:19)

-ansi是一个过时的开关,它要求编译器根据已有30年历史的过时的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语言,或最新的2018年版本。

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

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

-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 ++,听起来很愚蠢。

答案 3 :(得分:14)

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

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

答案 4 :(得分:6)

如果您的代码需要可移植,那么您可以测试它是否在没有任何gcc扩展或其他非标准功能的情况下进行编译。如果你的代码用-pedantic -ansi编译,那么理论上它应该用任何其他ANSI标准编译器编译好。

答案 5 :(得分:3)

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

答案 6 :(得分:1)

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

main函数返回void。这不是由标准定义的,这意味着它只适用于某些编译器(包括GCC),而不适用于其他编译器。顺便说一句,int main()int main(int, char**)是标准确定的两个签名。

另一个流行的扩展是能够在其他函数中声明和定义函数:

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

    // ...
    g();
    // ...
}

这是非标准的。如果您想要这种行为,请查看C++11 lambdas

答案 7 :(得分:0)

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