When I ask to see the current version of cc I get this.
$ cc --version
cc (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2
Copyright (C) 2012 Free Software Foundation, I
Default gcc command is the GNU dialect of ISO C90 (including some C99 features). This is the default for C code.
One thing to be aware of, the -std= option to gcc can not be used to "sandbox" the compiler into not supporting constructs from later versions of standard C. This is true with or without -pedantic
You can not depend upon on gcc -std=c89 -pedantic
to give you errors or warnings if you try to compile using some C99 code constructs. In some cases it will, in others it will not. For example, it will happily compile code that uses the %zu
format specifier in a printf() call, even though it wasn't added until C99.
This is explained in depth in the gcc manual, available (if it's installed) by typing info gcc
or online here. The relevant section of the 4.7.2 manual is here.
By default, gcc does not conform to any of the ANSI/ISO C standards. The current default is equivalent to -std=gnu90
, which is the 1989/1990 standard with GNU-specific extensions. (Some diagnostics required by the language standard are not issued.) Version 5.1.0, released 2015-04-22, changed the default from -std=gnu90
to -std=gnu11
, as documented here.
If you want standard conformance, you can use any of the following:
-std=c90 -pedantic
-std=c99 -pedantic
-std=c11 -pedantic
-std=c90
can also be spelled -ansi
, -std=c89
, or -std=iso9899:1990
.
-std=iso9899:199409
supports the C90 standard plus the 1995 amendment, which added a few minor features (all of which are also in C99).
-std=c99
can also be spelled -std=c9x
or -std=iso9899:1999
(the name c9x
was used before the standard was published). C99 support is not quite complete, but it's close.
-std=c11
can also be spelled -std=c0x
or -std=iso9899:2011
(the name c0x
was used before the final standard was published; it was wrongly assumed that x
would not exceed 9). C11 support is also incomplete; the current status is summarized here.
The -pedantic
option causes gcc to print required diagnostics for violations of constraints and syntax rules. In some cases, those diagnostics are merely warnings -- and there's no easy way to distinguish between those warnings and other warnings that aren't required by the language. Replace -pedantic
by -pedantic-errors
to cause gcc to treat language violations as fatal errors.
A quick history of the standard:
__STDC_VERSION__
and __STDC_LIB_EXT1__
.ANSI did not issue its own versions of the 1999 or 2011 standards, adopting the ISO standards instead.
N1256 is a freely available draft of the C99 standard, with the 3 Technical Corrigenda merged into it.
N1570 is a freely available draft of the C11 standard. There are some minor differences between it and the published C11 standard, plus one Technical Corrigendum. For more details, see my answer to this question.
The first line will give your GCC version (4.7.2)
(Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2
When you compile your code, you can specify which C/C++ revision you want to use, by adding -std=c99
or -std=c99
...
Note gnu89
is used by default.
Minimal test program
If you feel like finding it out empirically without reading any manuals.
c.c
#include <stdio.h>
int main(void) {
#ifdef __STDC_VERSION__
printf("__STDC_VERSION__ = %ld \n", __STDC_VERSION__);
#endif
#ifdef __STRICT_ANSI__
puts("__STRICT_ANSI__");
#endif
return 0;
}
Test with:
#!/usr/bin/env bash
for std in c89 c99 c11 c17 gnu89 gnu99 gnu11 gnu17; do
echo $std
gcc -std=$std -o c.out c.c
./c.out
echo
done
echo default
gcc -o c.out c.c
./c.out
Outcome:
c89
__STRICT_ANSI__
c99
__STDC_VERSION__ = 199901
__STRICT_ANSI__
c11
__STDC_VERSION__ = 201112
__STRICT_ANSI__
c17
__STDC_VERSION__ = 201710
__STRICT_ANSI__
gnu89
gnu99
__STDC_VERSION__ = 199901
gnu11
__STDC_VERSION__ = 201112
gnu17
__STDC_VERSION__ = 201710
default
__STDC_VERSION__ = 201710
Conclusion: gnu17
is used by default:
__STRICT_ANSI__
: GCC extension that is defined for -std=c
but not for -std=gnu
, see: https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html__STDC_VERSION__
: C99+ ANSI C macro that set for each version. Not present in C89 where it was not yet defined by the standard.For an explanation of -std=gnu*
vs -std=c*
see also: What are the differences between -std=c++11 and -std=gnu++11?
C++
main.cpp
#include <iostream>
int main(void) {
#ifdef __cplusplus
std::cout << __cplusplus << std::endl;
#endif
#ifdef __STRICT_ANSI__
std::cout << "__STRICT_ANSI__" << std::endl;
#endif
return 0;
}
Test with:
#!/usr/bin/env bash
for std in c++98 c++11 c++14 c++17 gnu++98 gnu++11 gnu++14 gnu++17; do
echo $std
g++ -std=$std -o cpp.out cpp.cpp
./cpp.out
echo
done
echo default
g++ -o cpp.out cpp.cpp
./cpp.out
Outcome:
c++98
199711
__STRICT_ANSI__
c++11
201103
__STRICT_ANSI__
c++14
201402
__STRICT_ANSI__
c++17
201703
__STRICT_ANSI__
gnu++98
199711
gnu++11
201103
gnu++14
201402
gnu++17
201703
default
201402
Conclusion: gnu++14
is the default:
__cplusplus
: macro defined by the C++ standard including on C++98 onwardsTested on Ubuntu 18.10, GCC 8.2.0. GitHub upstream.
useful information from info gcc
for gcc6 and https://gcc.gnu.org/onlinedocs/gcc-5.4.0/gcc/Standards.html#Standards for gcc5
6.3.1
- 10.1.0
2.1 C Language
==============
The default, if no C language dialect options are given, is
'-std=gnu11'.
2.2 C++ Language
================
The default, if no C++ language dialect options are given, is
'-std=gnu++14'.
5.4.0
2.1 C Language
==============
The default, if no C language dialect options are given, is -std=gnu11
2.2 C++ Language
================
The default, if no C++ language dialect options are given, is -std=gnu++98
For C, default mode remains std=gnu11
, but for C++ it has jumped from std=gnu++98
to std=gnu++14