ChatGPT解决这个技术问题 Extra ChatGPT

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

This note says:

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

First things first:

What is the purpose of the -pedantic and -ansi options of the GCC/G++ compiler (I couldn't understand the above description)?

What are the right circumstances for using these two options?

When should I use them?

Are they important?


J
Jonathan Leffler

I use it all the time in my coding.

The -ansi flag is equivalent to -std=c89. As noted, it turns off some extensions of GCC. Adding -pedantic turns off more extensions and generates more warnings. For example, if you have a string literal longer than 509 characters, then -pedantic warns 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.


@huahsin68: well, more or less. MSVC is a rather different compiler from most others, more adapted to its particular ecosystem and not available outside it. It does a lot of things its own way - which is not the same as the standard. Nevertheless, if you stay with the standard headers and so on, then MSVC and GCC are fairly similar. However, using -std=c89 -pedantic does mean you can move more easily between different compilers on other platforms. As soon as you start using <windows.h>, compatibility with other systems becomes problematic.
@slf: Because like every other vendor (albeit that GNU doesn't sell their compiler for cash), they would like you to use their proprietary features? Or, more generally, because they consider the extensions useful and think they should be enabled by default.
For whatever it is worth, and JFTR, I've mostly stopped using -pedantic, but most of my code still compiles OK when I re-enable it (the one program that didn't was explicitly using __int128 types, which are pedantically incorrect). I think there was an intervening stage when GCC was too noisy (for my liking) with -pedantic. I just tested about 300 source files — some library code, some commands, some SO test programs — and there was just the one to-be-expected problem. Currently using GCC 4.8.2 on Mac OS X 10.9.2.
@JonathanLeffler, Yes, I'm querying what's the name of an actual compiler in practice where that would not work? Is there even one such compiler?
Note that gcc predates the Standard, and I suspect the authors wanted the Standard to include some of the gcc features that were excluded from C89. The -pedantic flag basically served to flag things which the authors of gcc thought quality compilers should support. The gcc authors' attitude toward the Standard was very different from its maintainers' attitude today.
P
Peter Mortensen

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-errors option 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.


The ISO C and C++ standards only "prohibit extensions" in that the extension must not change the behaviour of any conforming program. The compiler is not forced to reject any program that uses extensions.
@M.M: It's important to note that when some compilers would accept a useful construct and others would reject it, the Committee's "compromise" was to have conforming implementation must issue a diagnostic which programmers could then ignore, thus avoiding the need for the Committee to either mandate or forbid the construct.
Note that -pedantic-errors is not the same thing as -Werror=pedantic. They perform different checks.
P
Peter Mortensen

<-ansi is 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 corrigenda to C90 have been standardized by ISO. Thus it is more apt to use the -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.

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 -pedantic is 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

struct test {
    int zero_size_array[0];
};

The C11 draft n1570 paragraph 6.7.6.2p1 says:

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.[...]

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:

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)

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

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

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.

The last part of the question was about using -ansi with 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.


Note that there have been further revisions of the language standard. Today I typically compile with -std=c11 -Wall -Wextra -Wpedantic -Wconversion.
I would additionally add that you should always specify the standard explicitly. For example -std=c++20.
P
Peter Mortensen

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.

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).


P
Peter Mortensen

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


-pedantic doesn't turn off all extensions, it leaves on a bunch of double-underscore stuff. So it might be more accurate to say that if your code compiles with -pedantic -ansi, and it also looks plausibly like it might compile on other implementations, then it will compile.
You mention double-underscore stuff, this sound interesting. What exactly are you refering to?
One example is gcc's "__asm__()" inline assembly code that is fine for gcc but that double underscore thing may not work on say a Windows compiler, even if that compiler did comply with the standard.
D
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.


under some versions of GCC !
C
Community

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

The main function 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.

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


P
Peter Mortensen

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


This is so interesing. You mention GNU C extension, and those extension may and may not be in ANSI standard. Can I have more info regarding to this. Where can I get those appropriate resource?