代码之家  ›  专栏  ›  技术社区  ›  huahsin68

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

  •  115
  • huahsin68  · 技术社区  · 15 年前

    This note 说:

    -ansi :告诉编译器实现ANSI语言选项。这转弯 关闭GCC的某些“特征”,其中 与ANSI不兼容 标准。

    -pedantic :与一起使用 ANSI ,这告诉编译器要严格遵守ANSI标准, 拒绝任何不是 顺从的

    首先要做的是:

    • 目的是什么 学究式的 ANSI gcc/g++编译器的选项(我不明白上面的描述)?
    • 有人能告诉我使用这两个选项的正确情况吗?
    • 我什么时候应该使用它们?
    • 它们重要吗?
    8 回复  |  直到 6 年前
        1
  •  73
  •   Wazery    14 年前

    如果可能的话,gcc编译器总是尝试编译您的程序。然而,在一些 案例中,C和C++标准规定禁止某些扩展。合格编译器 如gcc或g++在遇到这些扩展时必须发出诊断。例如, gcc编译器_s-pedantic选项导致gcc在这种情况下发出警告。使用更严格的 -pedantic-errors 选项将这些诊断警告转换为将导致编译的错误 在这一点上失败。只有那些非ISO结构需要由一致性标记 编译器将生成警告或错误。

        2
  •  96
  •   Jonathan Leffler    15 年前

    我总是在编码时使用它。

    这个 -ansi 标志等价于 -std=c89 . 如前所述,它关闭了GCC的一些扩展。添加 -pedantic 关闭更多扩展并生成更多警告。例如,如果字符串长度超过509个字符,则 学究式的 警告,因为它超过了C89标准所要求的最低限度。也就是说,每个C89编译器必须接受长度为509的字符串;允许它们接受更长的字符串,但是如果您是学究式的,使用更长的字符串是不可移植的,即使编译器允许接受更长的字符串,并且没有学究式的警告,GCC也会接受它们。

        3
  •  16
  •   Antti Haapala -- Слава Україні    6 年前

    -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标准 .

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

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


    这个 -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 ,不生成警告。

    学究式的 使编译器 符合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-errors )以确保GCC确实符合本标准的要求。


    问题的最后一部分是关于使用 ANSI 具有 C++ . ANSI从来没有标准化C++语言——只从ISO中使用它,所以这和说“法国标准化英语”一样有意义。然而,GCC似乎仍然接受C++,听起来很愚蠢。

        4
  •  14
  •   Francisco Soto    15 年前

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

    第一个,关闭gcc的特定特性。(ANSI) 第二个,将抱怨任何不符合标准的东西(不仅是GCC的特定特性,而且是您的构造)。

        5
  •  5
  •   Paul R    15 年前

    如果你的代码需要 便携式的 然后,您可以测试它是否在没有任何GCC扩展或其他非标准特性的情况下编译。如果您的代码与 -pedantic -ansi 从理论上讲,它应该可以与任何其他的ANSI标准编译器一起编译。

        6
  •  3
  •   Damien_The_Unbeliever    15 年前

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

        7
  •  1
  •   Community CDub    8 年前

    其他人回答得很充分。我只想添加一些常见扩展的示例:

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

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

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

    这是不标准的。如果你想要这种行为,看看 C++11 lambdas

        8
  •  0
  •   Martin Konecny    15 年前

    Pedantic这样做是为了让GCC编译器拒绝所有GNUC扩展,而不仅仅是那些使其与ANSI兼容的扩展。