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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2855121/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 11:17:47  来源:igfitidea点击:

What is the purpose of using -pedantic in GCC/G++ compiler?

c++cgccg++

提问by huahsin68

This notesays:

这篇笔记说:

-ansi: tells the compiler to implement the ANSI language option. This turns off certain "features" of GCC which are incompatible with the ANSI standard.

-pedantic: used in conjunction with -ansi, this tells the compiler to be adhere strictly to the ANSI standard, rejecting any code which is not compliant.

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

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

First things first:

第一件事:

  • What is the purpose of the -pedanticand -ansioptions of the GCC/G++ compiler (I couldn't understand the above description)?
  • Can anyone tell me the right circumstances for using these two options?
  • When should I use them?
  • Are they important?
  • GCC/G++ 编译器的-pedantic-ansi选项的目的是什么(我无法理解上面的描述)?
  • 谁能告诉我使用这两个选项的正确情况?
  • 我应该什么时候使用它们?
  • 它们重要吗?

采纳答案by Wazery

GCC compilers always try to compile your program if this is at all possible. However, in some cases, the C and C++ standards specify that certain extensions are forbidden. Conforming compilers such as gcc or g++ must issue a diagnostic when these extensions are encountered. For example, the gcc compiler's -pedantic option causes gcc to issue warnings in such cases. Using the stricter -pedantic-errorsoption converts such diagnostic warnings into errors that will cause compilation to fail at such points. Only those non-ISO constructs that are required to be flagged by a conforming compiler will generate warnings or errors.

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

回答by Jonathan Leffler

I use it all the time in my coding.

我一直在编码中使用它。

The -ansiflag is equivalent to -std=c89. As noted, it turns off some extensions of GCC. Adding -pedanticturns off more extensions and generates more warnings. For example, if you have a string literal longer than 509 characters, then -pedanticwarns about that because it exceeds the minimum limit required by the C89 standard. That is, every C89 compiler must accept strings of length 509; they are permitted to accept longer, but if you are being pedantic, it is not portable to use longer strings, even though a compiler is permitted to accept longer strings and, without the pedantic warnings, GCC will accept them too.

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

回答by Antti Haapala

-ansiis an obsolete switch that requests the compiler to compile according to the 30-year-old obsolete revision of C standard, ISO/IEC 9899:1990, which is essentially a rebranding of the ANSI standard X3.159-1989 "Programming Language C. Why obsolete? Because after C90 was published by ISO, ISO has been in charge of the C standardization, and any technical corrigendato C90 has been published by ISO. Thus it is more apt to use the -std=c90.

-ansi是一个过时的开关,其请求编译器根据30岁的编译的C标准过时修订ISO / IEC 9899:1990,这基本上是ANSI标准的一个更名X3.159-1989“C语言编程。为什么过时了?因为在C90被ISO发布后,ISO一直负责C的标准化,对C90的任何技术勘误都是由ISO发布的,所以更倾向于使用-std=c90.

Without this switch, the recent GCC C compilers will conform to the C language standardized in ISO/IEC 9899:2011, or the newest 2018 revision.

如果没有此开关,最近的 GCC C 编译器将符合ISO/IEC 9899:2011或最新的 2018 修订版中标准化的 C 语言。

Unfortunately there are some lazy compiler vendors that believe it is acceptable to stick to an older obsolete standard revision, for which the standardization document is not even available from standard bodies.

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

Using the switch helps ensuring that the code should compile in these obsolete compilers.

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



The -pedanticis an interesting one. In absence of -pedantic, even when a specific standard is requested, GCC will still allow some extensions that are not acceptable in the C standard. Consider for example the program

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

struct test {
    int zero_size_array[0];
};

The C11 draft n1570 paragraph 6.7.6.2p1 says:

C11草案n1570款6.7.6.2p1说

In addition to optional type qualifiers and the keyword static, the [ and ] may delimit an expression or *. If they delimit an expression (which specifies the size of an array), the expression shall have an integer type. If the expression is a constant expression, it shall have a value greater than zero.[...]

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

The C standard requires that the array length be greater than zero; and this paragraph is in the constraints; the standard says the following 5.1.1.3p1:

C 标准要求数组长度大于零;这一段是在约束中;标准说以下5.1.1.3p1

A conforming implementation shall produce at least one diagnostic message (identified in an implementation-defined manner) if a preprocessing translation unit or translation unit contains a violation of any syntax rule or constraint, even if the behavior is also explicitly specified as undefined or implementation-defined. Diagnostic messages need not be produced in other circumstances.9)

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

However, if you compile the program with gcc -c -std=c90 pedantic_test.c, no warning is produced.

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

-pedanticcauses the compiler to actually comply to the C standard; so now it will produce a diagnostic message, as is required by the standard:

-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];
         ^~~~~~~~~~~~~~~

Thus for maximal portability, specifying the standard revision is not enough, you must also use -pedantic(or -pedantic-errors) to ensure that GCC actually does comply to the letter of the standard.

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



The last part of the question was about using -ansiwith C++. ANSI never standardized the C++ language - only adopting it from ISO, so this makes about as much sense as saying "English as standardized by France". However GCC still seems to accept it for C++, as stupid as it sounds.

这个问题的最后一部分是有关使用-ansiC ++。ANSI 从未对 C++ 语言进行标准化——只是从 ISO 那里采用了它,所以这与说“法国标准化的英语”一样有意义。然而,GCC 似乎仍然接受 C++,这听起来很愚蠢。

回答by Francisco Soto

Basically, it will make your code a lot easier to compile under other compilers which also implement the ANSI standard, and, if you are careful in which libraries/api calls you use, under other operating systems/platforms.

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

The first one, turns off SPECIFIC features of GCC. (-ansi) The second one, will complain about ANYTHING at all that does not adhere to the standard (not only specific features of GCC, but your constructs too.) (-pedantic).

第一个,关闭 GCC 的特定功能。(-ansi) 第二个,会抱怨任何不符合标准的东西(不仅是 GCC 的特定功能,还有你的结构。)(-pedantic)。

回答by Paul R

If your code needs to be portablethen you can test that it compiles without any gcc extensions or other non-standard features. If your code compiles with -pedantic -ansithen in theory it should compile OK with any other ANSI standard compiler.

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

回答by Damien_The_Unbeliever

If you're writing code that you envisage is going to be compiled on a wide variety of platforms, with a number of different compilers, then using these flags yourself will help to ensure you don't produce code that only compiles under GCC.

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

回答by Enn Michael

Others have answered sufficiently. I would just like to add a few examples of frequent extensions:

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

The mainfunction returning void. This is not defined by the standard, meaning it will only work on some compilers (including GCC), but not on others. By the way, int main()and int main(int, char**)are the two signatures that the standard does define.

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

Another popular extension is being able to declare and define functions inside other functions:

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

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

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

This is nonstandard. If you want this kind of behavior, check out C++11 lambdas

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

回答by Martin Konecny

Pedantic makes it so that the gcc compiler rejects all GNU C extensions not just the ones that make it ANSI compatible.

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