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

xxhby3vn  于 2023-02-07  发布在  其他
关注(0)|答案(7)|浏览(270)

当我要求查看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中的哪一个。

pengsaosao

pengsaosao1#

这在gcc手册中有详细的解释,可以通过输入info gcc或在线here获得(如果安装了),当前手册的相关章节是here,但它可能与您使用的版本对应,也可能不对应。
自从我在2013年发布这个答案以来,其中一些信息已经发生了变化,并且将继续变化。如果你在2023年左右阅读到这篇文章,当前的版本可能是-std=gnu17(C17带有GNU特定的扩展;C17是对C11的一个小的更新)。你应该检查一下你正在使用的版本的文档。C23标准还没有发布,但是应该很快就会真实的。我不能预测gcc什么时候会切换到-std=gnu23作为它的默认值。如果你在遥远的将来阅读这篇文章,让我们知道事情的结果。
gcc版本从3.0到4.9.4默认为-std=gnu89-std=gnu90
gcc版本从5.5到10.4默认为-std=gnu11(它们跳过了-std=gnu99,尽管您仍然可以指定它)。
gcc版本11.3和12.2默认为std=gnu17
默认情况下,gcc不符合任何ANSI/ISO C标准。当前默认值相当于-std=gnu17,这是具有特定于GNU的扩展的2017标准。(未发布语言标准所需的某些诊断。)早期版本的gcc默认为-std=gnu90-std=gnu11
如果要符合标准,可以使用以下任一项:

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

-std=c90也可以拼写为-ansi-std=c89-std=iso9899:1990
-std=iso9899:199409支持C90标准加上1995年的修正案,该修正案增加了一些次要特性(所有这些特性也在C99中)。
-std=c99也可以拼写为-std=c9x-std=iso9899:1999c9x是在标准发布之前使用的名称)。
-std=c11也可以拼写为-std=c0x-std=iso9899:2011(名称c0x在最终标准发布之前使用;错误地假定x不超过9). C11支持也不完全;当前状态是summarized here
-pedantic选项使gcc打印违反约束和语法规则所需的诊断信息。在某些情况下,这些诊断信息仅仅是警告--并且没有简单的方法来区分这些警告和语言不需要的其他警告。用-pedantic-errors替换-pedantic会使gcc将违反语言视为致命错误。
该标准的简要历史:

  • C89是第一个正式的C语言标准,由ANSI于1989年发布。
  • C90是该标准的ISO版本,描述了与C89完全相同的语言。ANSI正式采用了ISO版本的标准。有两个技术勘误表,纠正了一些错误。
  • C95是C90的修正案,增加了几个特性,主要是有向图和广泛的字符支持,据我所知,合并版本从未出版过。
  • C99由ISO于1999年发布,有三个技术勘误表。
  • C11由ISO于2011年发布,有一个技术勘误表,固定了__STDC_VERSION____STDC_LIB_EXT1__的定义。
  • C17由ISO于2017年发布,仅是对C11的微小更新。
  • C23将于2023年发布(在我写这篇文章的时候,它已经接近定稿,但文件仍在编辑中)。

ANSI没有发布自己的1999年或以后版本的标准,而是采用了ISO标准。
N1256是C99标准的免费草案,其中合并了3个技术勘误表。
N1570是C11标准的免费草案。它与已发布的C11标准之间存在一些细微差异,外加一个技术勘误表。有关详细信息,请参见my answerthis question

9rnv2umw

9rnv2umw2#

gcc 6的有用信息来自info gcc,gcc 5的有用信息来自https://gcc.gnu.org/onlinedocs/gcc-5.4.0/gcc/Standards.html#Standards

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

wb1gzix0

wb1gzix03#

    • 最小测试程序**

如果你想不看任何手册就凭经验找到答案。
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;
}

测试条件:

#!/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*的解释,另请参见:What are the differences between -std=c11 and -std=gnu11?

    • 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上进行了测试。

bvn4nwqk

bvn4nwqk4#

第一行将给予GCC版本(4.7.2)
(Ubuntu/Linaro 4.7.2-2ubuntu1)4.7.2
编译代码时,可以指定要使用的C/C++修订版,方法是添加-std=c99-std=c99...
注意默认情况下使用gnu89

uurv41yg

uurv41yg5#

需要注意的一点是,gcc的-std=选项不能用于将编译器“沙箱化”到不支持来自标准C的更高版本的构造中。无论是否使用-pedantic,都是如此
如果你试图使用一些C99代码结构编译,你不能依赖gcc -std=c89 -pedantic给予你错误或警告。在某些情况下它会,在其他情况下它不会。例如,它会很高兴地编译在printf()调用中使用%zu说明符的代码,即使它直到C99才被添加。

ckx4rj1h

ckx4rj1h6#

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

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

ccrfmcuu7#

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

相关问题