如何找到我当前的编译器标准,如果它是C90等

时间:2011-02-14 11:40:00

标签: c compiler-construction c99 c89

我正在使用Linux机器。是否有任何系统命令可以找到我正在使用的C编译器后面的标准?

8 个答案:

答案 0 :(得分:22)

这是依赖于编译器的,我假设你正在使用GCC。 您可以使用以下命令检查编译器定义的宏:

gcc -dM -E - < /dev/null

特别检查manual about the flags

__ STDC_VERSION __

  

此宏扩展为C标准版   版本号,一个长整数   形式为yyyymmL的常数   yyyy和mm是年份和月份   标准版。这表示   哪个版本的C标准版   编译器符合。喜欢 STDC ,   这不一定准确   整个实现,除非GNU   CPP正在与GCC一起使用。

     

值199409L表示1989 C   1994年修订的标准,即   目前的默认值;值199901L   表示1999年的C修订版   标准。支持1999年   修订尚未完成。

     

如果没有定义此宏   使用-traditional-cpp选项,也不用于编译C ++或Objective-C。

this site中,您可以找到很多有关此内容的信息。请参阅现有表here

答案 1 :(得分:11)

您也可以使用标准宏在代码中对此进行测试,例如(最初来自同名的sourceforge项目):

#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

如果你想从命令行检查一下,你可以选择一个(例如c89)并检查最小程序的返回值:

echo -e "#ifdef __STDC__\n#error\n#endif"|gcc -xc -c - > /dev/null 2>&1; test $? -eq 0  || echo "c89

答案 2 :(得分:6)

在编译时,检查预处理器宏:

  • __ANSI__
  • __STDC__
  • __STDC_VERSION__&gt; = 199901L for c99

答案 3 :(得分:4)

你可能有gcc,在这种情况下你可以在编译时指定标准,例如

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

或:

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

类型:

$ man gcc

了解详情。

答案 4 :(得分:1)

为了从命令行确定您的编译器支持的 C 版本,只需键入:

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

将 gcc 替换为您要检查的编译器。

如果编译器支持 C89(也称为 ANSI C)或 ISO C90,您将看到 __STDC__ 根据标准定义为 1。 (但有时__STDC__ 被设置为其他一些非零值)。 C89 与 C90 相同。 C89 已被 ANSI 批准。一年后,ISO 批准了 ANSI 标准。 ISO 标准称为 C90。

ISO C90 标准经过修订,非正式地称为 C95。 (有时也称为 C94。但更常用的是 C95)。

如果编译器支持 C95 或更高版本,您将看到定义了 __STDC_VERSION__。该值将因版本而异。 (例如,C99 会将 __STDC_VERSION__ 定义为 199901L 的值)。见https://sourceforge.net/p/predef/wiki/Standards/

如果您想检查 C 程序中的版本,请尝试以下代码:

#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;
}

以下是使用 www.onlinegdb.com 中的 C 编译器的程序的输出:

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

答案 5 :(得分:0)

如果您的C编译器是gcc,您可以使用-std选项指定要遵循的C标准。默认值为gnu89。没有通用的系统命令来确定任何给定编译器的标准。您需要查看文档。

答案 6 :(得分:0)

我相信 Tarantula 的答案并不完全正确 - 因为 c89 和 c90 是相同的标准(至少被 clang 和 gcc 以这种方式处理),并且没有定义 __STDC_VERSION__。也没有 ISO C 1994 标准;有一个 1995 年的修正案 - 我不认为这是单独支持的。

所以也许是这样的:

#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
#    endif
#  else
#      define C_LANGUAGE_STANDARD 1990
#  endif
#else
#      define C_LANGUAGE_STANDARD 1972
#endif

会更合适吗?

答案 7 :(得分:-1)

除上述答案外。如果您想检查您是否使用C99。 只需定义一个结构并将其初始化为:

struct Tree{
    struct Node *root;
    struct Node NIL_t;
    struct Node * const NIL;    
}

struct Tree t = { .root = NULL, .NIL = &t.NIL_t }; //init.

这仅适用于C99。如果没有,那么你没有使用C99。