43

I'm working on a Linux machine. Is there any system command to find the standard followed by the C compiler I'm using?

Paul R
  • 208,748
  • 37
  • 389
  • 560
Hemanth
  • 5,035
  • 9
  • 41
  • 59

7 Answers7

38

This is compiler dependent, I'm supposing you're using GCC. You could check your compiler defined macros using:

gcc -dM -E - < /dev/null

Check the manual about the flags, specially:

###__STDC_VERSION__###

This macro expands to the C Standard's version number, a long integer constant of the form yyyymmL where yyyy and mm are the year and month of the Standard version. This signifies which version of the C Standard the compiler conforms to. Like __STDC__, this is not necessarily accurate for the entire implementation, unless GNU CPP is being used with GCC.

The value 199409L signifies the 1989 C standard as amended in 1994, which is the current default; the value 199901L signifies the 1999 revision of the C standard. Support for the 1999 revision is not yet complete.

This macro is not defined if the -traditional-cpp option is used, nor when compiling C++ or Objective-C.

In this site you can find a lot of information about this. See the table present here.

mtraceur
  • 3,254
  • 24
  • 33
Tarantula
  • 19,031
  • 12
  • 54
  • 71
18

You can also test this in your code using standard macros, for example (originally from sourceforge project of the same name):

#if defined(__STDC__)
# define PREDEF_STANDARD_C_1989
# if defined(__STDC_VERSION__)
#  define PREDEF_STANDARD_C_1990
#  if (__STDC_VERSION__ >= 199409L)
#   define PREDEF_STANDARD_C_1994
#  endif
#  if (__STDC_VERSION__ >= 199901L)
#   define PREDEF_STANDARD_C_1999
#  endif
#  if (__STDC_VERSION__ >= 201710L)
#   define PREDEF_STANDARD_C_2018
#  endif
# endif
#endif

If you want to check this from the command line you can pick one (e.g. c89) and check the return value from a minimal program:

echo -e "#ifdef __STDC__\n#error\n#endif"|gcc -xc -c - > /dev/null 2>&1; test $? -eq 0  || echo "c89
Flexo
  • 87,323
  • 22
  • 191
  • 272
8

At compile time, check against preprocessor macro:

  • __ANSI__
  • __STDC__
  • __STDC_VERSION__ >= 199901L for c99
Yann Droneaud
  • 5,277
  • 1
  • 23
  • 39
5

You probably have gcc, in which case you can specify the standard at compile-time, e.g.

$ gcc -Wall -std=c89 foo.c -o foo

or:

$ gcc -Wall -std=c99 foo.c -o foo

Type:

$ man gcc

for full details.

Paul R
  • 208,748
  • 37
  • 389
  • 560
  • 1
    Typo: "... and NOT how to define ..." – Tarantula Feb 14 '11 at 17:16
  • 1
    @Tarantula: thanks, yes, you may have a point. I assumed the OP was not aware that you had control over the standard used, hence my answer, but perhaps that was a bad assumption. – Paul R Feb 14 '11 at 17:29
5

In order to determine the version of C that your compiler supports from the command line, just type:

gcc -dM -E - < /dev/null | grep "__STDC_"

Replace gcc with the compiler you want to check.

If the compiler supports C89 (also called ANSI C) or ISO C90, you will see __STDC__ defined to be 1 according to the standard. (But sometimes__STDC__ is set to some other non-zero value). C89 is identical to C90. C89 was ratified by ANSI. A year later the ISO ratified the ANSI standard. The ISO standard is called C90.

The ISO C90 standard was amended and is informally called C95. (Sometimes, it is also called C94. But C95 is more commonly used). The ISO has also ratified C99, C11 (in 2011) and C17 (in 2017).

If the compiler supports C95 or later, you will see __STDC_VERSION__ defined. The value will vary depending on the version. (e.g. C99 will have __STDC_VERSION__ defined to the value of 199901L). See https://sourceforge.net/p/predef/wiki/Standards/

If you want to check the version within your C program, try this code:

#include <stdio.h>
#include <math.h>       // Needed for INFINITY, HUGE_VAL, HUGE_VALF & HUGE_VALL
                        // constants (or macros)
#if !defined(__STDC__)
#   define __STDC__ 0
#endif

#if !defined(__STDC_VERSION__) 
#   define __STDC_VERSION__ 0
#endif


int main()
{
    if (!__STDC__ && !__STDC_VERSION__) printf("The C compiler does not comply with the C89 or later standard!\nIt likely complies with the 1978 K&R C standard (informally known as C78).\n");
    else if (__STDC_VERSION__ >= 201710L) printf("The C compiler complies with the C17 standard.\n");
    else if (__STDC_VERSION__ >= 201112L) printf("The C compiler complies with the C11 standard.\n");
    else if (__STDC_VERSION__ >= 199901L) printf("The C compiler complies with the C99 standard.\n");
    else if (__STDC_VERSION__ >= 199409L) printf("The C compiler complies with the amended C90 standard (also known as C95).\n");
    else if (__STDC__) printf("The C compiler complies with the ANSI C89 / ISO C90 standard.\n");
   
    puts("");
    if (__STDC__) printf("\"__STDC__\": %ld\n", __STDC_VERSION__);
    if (__STDC_VERSION__) printf("\"__STDC_VERSION__\": %ld\n\n", __STDC_VERSION__);
    
    puts("");
    if (__STDC_VERSION__ >= 199901L) printf(" INFINITY (added in C99): %f\n", INFINITY );    // Also works with %lf and %Lf
    if (__STDC_VERSION__ >= 199901L) printf("-INFINITY (added in C99): %f\n", -INFINITY );   // Also works with %lf and %Lf
    
    puts("");
    if (__STDC_VERSION__ >= 199901L) printf(" HUGE_VALF (added in C99): %f\n", HUGE_VALF );
    if (__STDC_VERSION__ >= 199901L) printf("-HUGE_VALF (added in C99): %f\n", -HUGE_VALF );
    
    puts("");
    if (__STDC__) printf(" HUGE_VAL (added in C89 (ANSI) which is the same as C90 (ISO)): %lf\n", HUGE_VAL );
    if (__STDC__) printf("-HUGE_VAL (added in C89 (ANSI) which is the same as C90 (ISO)): %lf\n", -HUGE_VAL );

    puts("");
    if (__STDC_VERSION__ >= 199901L) printf(" HUGE_VALL (added in C99): %Lf\n", HUGE_VALL );
    if (__STDC_VERSION__ >= 199901L) printf("-HUGE_VALL (added in C99): %Lf\n", -HUGE_VALL );

    return 0;
}

Below is the output of this program using the C compiler from www.onlinegdb.com :

The C compiler complies with the C99 standard.

"__STDC__": 199901
"__STDC_VERSION__": 199901


 INFINITY (added in C99): inf
-INFINITY (added in C99): -inf

 HUGE_VALF (added in C99): inf
-HUGE_VALF (added in C99): -inf

 HUGE_VAL (added in C89 (ANSI) which is the same as C90 (ISO)): inf
-HUGE_VAL (added in C89 (ANSI) which is the same as C90 (ISO)): -inf

 HUGE_VALL (added in C99): inf
-HUGE_VALL (added in C99): -inf
RobK
  • 156
  • 1
  • 9
1

If your C compiler is gcc, you can use the -std option to specify which C standard to follow. The default is gnu89. There's no general system command to determine the standard for any given compiler. You'll need to check the documentation.

ciaron
  • 1,089
  • 7
  • 15
  • 1
    You can check, by writing a small program using standard macros. – Flexo Feb 14 '11 at 11:48
  • 1
    Nice, yes. I just wrote a small test, but `__STDC_VERSION__` is undefined for the gcc default standard (gnu89). – ciaron Feb 14 '11 at 12:38
0

I believe Tarantula's answer is not exactly correct - as c89 and c90 are the same standard (and treated that way by clang and gcc at least), and don't have __STDC_VERSION__ defined.

So maybe something like:

#if defined(__STDC__)
#  if defined(__STDC_VERSION__)
#    if (__STDC_VERSION__ >= 201710L)
#      define C_LANGUAGE_STANDARD 2018
#    elif (__STDC_VERSION__ >= 201112L)
#      define C_LANGUAGE_STANDARD 2011
#    elif (__STDC_VERSION__ >= 199901L)
#      define C_LANGUAGE_STANDARD 1999
#    elif (__STDC_VERSION__ >= 199409L)
#      define C_LANGUAGE_STANDARD 1995
#    endif
#  else
#      define C_LANGUAGE_STANDARD 1990
#  endif
#else
#      define C_LANGUAGE_STANDARD 1972
#endif

would be more fitting?

einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • You are right. C89 and C90 are the same standard. C89 was ratified by ANSI. And C90 was ratified by ISO. Both just define `__STDC__`. Neither C89 or C90 use `__STDC_VERSION__`. See https://sourceforge.net/p/predef/wiki/Standards/ – RobK Aug 09 '21 at 21:00
  • P.S. Technically, you are correct. There is no C94 or C95 standard. There is an amended C90 standard which is informally known as C95. If the compiler complies with C95, `__STDC_VERSION__` will be set to 199409L. See https://sourceforge.net/p/predef/wiki/Standards/. (This web site refers to C95 as C94 which some people do. But C95 is more commonly used). – RobK Aug 10 '21 at 13:56
  • @RobK: And does any compiler compiles that way? – einpoklum Aug 10 '21 at 15:16
  • @einpoklim: Yes! Between 1995 and 1999, there were compilers that compiled with C95. Even today, gcc will compile in accordance with the C95 standard if you use the option -std=iso9899:199409. See https://gcc.gnu.org/onlinedocs/gcc/Standards.html . But I do not know why one would ever use C95 today. C99 is just C95 with great extra features thrown in. So a C99 compiler should be able to compile code written in accordance with C95 just fine. – RobK Aug 11 '21 at 16:50