当前 GCC 的默认 C-std 标准版本是什么(尤其是在 Ubuntu 上) ?

当我要求查看当前版本的 cc 时,我得到了这个。

$ cc --version
cc (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


$

我想知道的是 c89 c90 c99还是 c11。

64765 次浏览

第一行将给出 GCC 版本(4.7.2)

(Ubuntu/Linaro 4.7.2-2ubuntu1)4.7.2

在编译代码时,可以通过添加 -std=c99-std=c99来指定要使用的 C/C + + 版本..。

注意,默认情况下使用 gnu89

这在 gcc 手册中有详细的解释,可以通过键入 info gcc或在线 给你来获得(如果已经安装)。4.7.2手册的相关部分是 给你

默认情况下,gcc 不符合任何 ANSI/ISO C 标准。当前的默认值相当于 -std=gnu90,这是1989/1990标准,带有特定于 GNU 的扩展名。(一些语言标准所要求的诊断没有发布。)发布于2015-04-22的5.1.0版本将默认值从 -std=gnu90更改为 -std=gnu11就像这里记录的一样

如果您想要标准一致性,可以使用以下任何一种:

-std=c90 -pedantic
-std=c99 -pedantic
-std=c11 -pedantic

-std=c90也可以拼写为 -ansi-std=c89-std=iso9899:1990

-std=iso9899:199409支持 C90标准加上1995年的修正案,增加了一些次要的功能(所有这些也是在 C99)。

-std=c99也可以拼写为 -std=c9x-std=iso9899:1999(标准发布前使用的名称为 c9x)。C99的支持是 还不完整,但它接近。

-std=c11也可以拼写为 -std=c0x-std=iso9899:2011(在最终标准发布之前使用了名称 c0x; 错误地认为 x不会超过9)。C11支持也是不完整的; 当前状态是 总结如下

-pedantic选项导致 gcc 打印所需的诊断信息,以查找违反约束和语法规则的情况。在某些情况下,这些诊断仅仅是警告——并且没有简单的方法来区分这些警告和语言不需要的其他警告。将 -pedantic替换为 -pedantic-errors会导致 gcc 将语言冲突视为致命错误。

标准简史:

  • C89是 ANSI于1989年发布的第一个官方 C 标准。
  • C90是该标准的 ISO版本,描述了与 C89完全相同的语言。ANSI 正式采用了 ISO 版本的标准。有两个技术勘误,纠正了一些错误。
  • C95是对 C90的修正,增加了一些特性,主要是有向图和宽字符支持。据我所知,合并后的版本从未发布过。
  • C99是国际标准化组织于1999年发布的。
  • C11于2011年由国际标准化组织(ISO)发布。有一个技术更正,确定了 __STDC_VERSION____STDC_LIB_EXT1__的定义。

ANSI 没有发布自己的1999年或2011年版本的标准,而是采用了 ISO 标准。

N1256 是免费提供的 C99标准草案,其中融入了3个技术勘误。

N1570 是免费提供的 C11标准草案。它与已发布的 C11标准之间有一些细微的差别,另外还有一个技术勘误。有关详细信息,请参阅 我的回答这个问题

需要注意的一点是,gcc 的-std = 选项不能用于“沙箱”编译器,使其不支持标准 C 的后续版本的构造。不管有没有 -pedantic,情况都是如此

如果尝试使用某些 C99代码构造进行编译,则不能依赖于 gcc -std=c89 -pedantic来提供错误或警告。在某些情况下,它会,在另一些情况下,它不会。例如,它将很高兴地在 printf ()调用中编译使用 %zu格式说明符的代码,尽管它直到 C99才被添加。

默认的 gcc 命令是 ISOC90的 GNU 方言(包括一些 C99特性)。这是 C 代码的默认值。

来自 info gcc的关于 gcc6的有用信息和来自 https://gcc.gnu.org/onlinedocs/gcc-5.4.0/gcc/Standards.html#Standards的关于 gcc5的有用信息

Gcc 版本 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'.

Gcc 版本 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

对于 C,默认模式仍然是 std=gnu11,但是对于 C + + ,它已经从 std=gnu++98跳到了 std=gnu++14

最小的测试程序

如果你想不用看任何手册就能凭经验找到答案的话。

抄送

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

测试:

#!/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

结果:

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

结论: gnu17默认使用:

有关 -std=gnu*-std=c*的解释,请参阅: - std = c + + 11和-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;
}

测试:

#!/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

结果:

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

结论: gnu++14是默认值:

  • __cplusplus: 由 C + + 标准定义的宏,包括从 C + + 98开始的宏

在 Ubuntu 18.10,GCC 8.2.0. GitHub 上游上测试。

我找到了一种查询 C + + 版本的方法,并将其改编为 C:

gcc -dM -E -x c  /dev/null | grep -F __STDC_VERSION__