155
votes

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?
8

8 Answers

119
votes

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.

102
votes

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.

30
votes

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

15
votes

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

8
votes

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.

4
votes

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.

2
votes

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

0
votes

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