Should I use “-ansi” or explicit “-std=…” as compi

2019-04-05 01:45发布

问题:

I've read that ANSI C is not exactly the same as ISO C and compilers may differ in interpretation of what "-ansi" is about. (gcc maps it to C90, clang maps it to C89) At the moment I would tend to use "-std=..." over "-ansi" as then it is explicitly shown which standard is used. As I am specifically interested in compiling on Linux, Windows and MAC, I fear some compilers could not understand "-std=..." but "-ansi". So are there any pros and cons for using the one over the other?

回答1:

If you want the compiler to enforce the 1989 ANSI C standard, or equivalently the 1990 ISO C standard (they describe exactly the same language), you can safely use either -ansi or -std=c89.

The name -ansi is, strictly speaking, incorrect; it refers to the 1989 ANSI C standard, but ANSI itself considers that standard to be obsolete; it was replaced by the 1999 ISO C standard (which ANSI officially adopted shortly after it was released) which itself either has been, or soon will be, replaced by the new 2011 ISO C standard. But changing the meaning of the -ansi option would break too many Makefiles and build scripts.

The gcc 4.7 and later versions also recognize -std=c90 as a synonym for -std=c89. gcc 4.7 was released in March 2012, so -std=c90 is reasonably portable unless you need to allow for older versions of gcc.

-std=c99 enforces (most of) the 1999 ISO C standard. Since Microsoft in particular doesn't support C99 (even after all these years), using this option means the compiler won't warn you about use of C99-specific features that might not be supported elsewhere. gcc's C99 support is documented here.

gcc 4.7 has partial support for the new ISO C 2011 standard, with -std=c11. That support has improved in later releases, but is not yet complete. gcc C11 status is documented here, and is said to be similar to the level of C99 support.

There are more options, and a number of aliases for the ones I've mentioned; for example, the option -std=c9x was added before the 1999 ISO standard was finalized, and it's still supported; similarly, -std=c1x is a synonym for -std=c11.

I believe that clang is intended to be as compatible as possible with gcc, so it should support the same options with the same meanings (except perhaps for some of the newer ones, depending on which versions of gcc and clang you're using).

The gcc manual has the full details, with one section describing the supported standards and another specifying the various -ansi and -std=... options. The links are to the 4.7 version. You can also run info gcc (if you have the GNU info command and the gcc documentation installed), or you can see multiple versions of the manual here.

If you're going to use compilers other than gcc (and compilers that aim to be gcc-compatible), you'll have to read their documentation to find out how to enforce various versions of the C standard.



回答2:

-ansi and -std= compiler flags may be shared by other compilers but they are gcc flags.

As of now -ansi is equivalent to -std=c89 in gcc but this may1) change in the future so I suggest you to use -std=c89 over -ansi. Indeed ISO c99 for example has also been ratified by ANSI.

You should note that c89 and c90 are essentially the same C Standard. c89 is the ANSI name while c90 is the ISO name.

From gcc page:

There were no technical differences between these publications, although the sections of the ANSI standard were renumbered and became clauses in the ISO standard. This standard, in both its forms, is commonly known as C89, or occasionally as C90, from the dates of ratification.


1) As noted by Keith Thompson in the comments, even though it's probably unlikely as it would break many build scripts.