c - 语言标准版本与编译器版本
问题描述
C
版本(例如C99
)和C
编译器版本(例如4.9.3
)有什么区别
$ ./arm-none-eabi-gcc --version
arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors) 4.9.3 20150529 (release) [ARM/embedded-4_9-branch revision 227977 with DYNAMIC_REENT by Ambarella]
Copyright (C) 2014 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.
如何判断我是否至少使用 C99,以便我可以利用某些宏。
解决方案
C 版本是 C 标准的名称。
按历史顺序排列的主要标准:
- K&R
- ANSI(又名 C89 用于 ANSI,C90 用于 ISO)
- C99
- C11
随着 C 语言在过去 40 年中的发展,这些标准中引入了新的或修改的特性。
gcc 编译器版本 - 只是软件的版本。旧版本可能不支持新的 C 标准。您可以使用命令行选项通知编译器您的代码符合什么标准:
2.1 C语言
最初的 ANSI C 标准 (X3.159-1989) 于 1989 年获得批准并于 1990 年发布。该标准于 1990 年晚些时候被批准为 ISO 标准 (ISO/IEC 9899:1990)。这些出版物之间没有技术差异,尽管 ANSI 标准的部分被重新编号并成为 ISO 标准中的条款。ANSI 标准,但不是 ISO 标准,也带有一个基本原理文档。从批准之日起,该标准的两种形式通常称为 C89,有时也称为 C90。要在 GCC 中选择此标准,请使用选项之一
-ansi
,-std=c90
或-std=iso9899:1990
; 要获得标准要求的所有诊断,您还应该指定-pedantic
(或-pedantic-errors
如果您希望它们成为错误而不是警告)。请参阅控制 C 方言的选项。1990 ISO C 标准中的错误在 1994 年和 1996 年发布的两个技术勘误中得到了纠正。GCC 不支持未纠正的版本。
1990 年标准的修订版于 1995 年发布。该修订版添加了二合字母和
__STDC_VERSION__
语言,但其他方面与图书馆有关。该修正通常称为 AMD1;修订后的标准有时称为 C94 或 C95。要在 GCC 中选择此标准,请使用该选项-std=iso9899:199409
(与其他标准版本一样,-pedantic
接收所有必需的诊断)。ISO C 标准的新版本于 1999 年作为 ISO/IEC 9899:1999 发布,通常称为 C99。(在开发过程中,这个标准版本的草稿被称为 C9X。) GCC 基本上完全支持这个标准版本;有关详细信息,请参见 http://gcc.gnu.org/c99status.html。要选择此标准,请使用
-std=c99
或-std=iso9899:1999
。1999 ISO C 标准中的错误在 2001 年、2004 年和 2007 年发布的三个技术勘误中得到了更正。GCC 不支持未更正的版本。
C 标准的第四个版本,称为 C11,于 2011 年作为 ISO/IEC 9899:2011 发布。(在开发过程中,这个标准版本的草案被称为 C1X。)GCC 基本上完全支持这个标准,使用
-std=c11
或 启用-std=iso9899:2011
。集成了更正的版本称为 C17,支持-std=c17
或-std=iso9899:2017
;更正也适用于-std=c11
,选项之间的唯一区别是 的值__STDC_VERSION__
。默认情况下,GCC 为 C 语言提供了一些扩展,这些扩展在极少数情况下会与 C 标准冲突。请参阅 C 语言系列的扩展。C99 标准中的某些功能在 C90 模式中被接受为扩展,而 C11 标准中的某些功能在 C90 和 C99 模式中被接受为扩展。使用
-std
上面列出的选项会禁用与所选 C 标准版本冲突的这些扩展。您也可以使用-std=gnu90
(对于带有 GNU 扩展的 C90)、-std=gnu99
(对于带有 GNU 扩展的 C99)或-std=gnu11
(对于带有 GNU 扩展的 C11)显式选择 C 语言的扩展版本。如果没有给出 C 语言方言选项,则默认值为
-std=gnu11
.ISO C 标准定义(在第 4 节中)两类符合要求的实现。符合要求的托管实现支持整个标准,包括所有图书馆设施;一个符合要求的独立实现只需要提供某些库设施:那些在
<float.h>
、<limits.h>
、<stdarg.h>
和<stddef.h>
; 自 AMD1 以来,还有那些在<iso646.h>
; 从 C99 开始,还有<stdbool.h>
和中的那些<stdint.h>
;从 C11 开始,还有<stdalign.h>
和中的那些<stdnoreturn.h>
。此外,C99 中添加的复杂类型对于独立实现不是必需的。该标准还为程序定义了两种环境:一个独立环境,所有实现都需要,并且可能没有独立实现所需的库设施,其中程序启动和终止的处理是实现定义的;和一个托管环境,这不是必需的,其中提供了所有库设施,并且通过函数
int main (void)
或int main (int, char *[])
. 操作系统内核是在独立环境中运行的程序示例;使用操作系统设施的程序是在托管环境中运行的程序的一个示例。GCC 旨在用作符合标准的独立实现,或用作符合标准的托管实现的编译器。默认情况下,它充当托管实现的编译器,定义
__STDC_HOSTED__
为 1 并假定使用 ISO C 函数的名称时,它们具有标准中定义的语义。要使其作为独立环境的符合标准的独立实现,请使用选项-ffreestanding
; 然后它定义__STDC_HOSTED__
为 0 并且不对标准库中的函数名称的含义做出假设,下面提到的例外情况。要构建操作系统内核,您可能仍需要自行安排链接和启动。请参阅控制 C 方言的选项。GCC 不提供仅托管实现所需的库设施,也没有提供 C99 在所有平台上的独立实现所需的所有设施。要使用托管环境的设施,您需要在其他地方找到它们(例如,在 GNU C 库中)。请参阅标准库。
GCC 使用的大多数编译器支持例程都存在于 libgcc 中,但也有一些例外。GCC 要求独立环境提供 memcpy、memmove、memset 和 memcmp。最后,如果
__builtin_trap
使用了,并且目标没有实现陷阱模式,那么 GCC 会发出一个中止调用。有关在线提供的技术勘误、基本原理文档和有关 C 历史的信息的参考,请参阅 http://gcc.gnu.org/readings.html
推荐阅读
- swiftui - 按钮不会显示禁用的样式
- vba - 如何使用 Selenium 和 VBA 识别包含特殊字符的元素类名
- xml - powershell,xml,如何区分和元素
- kubernetes - 我们可以通过 Kiali 在代理后面使用 Istio 跟踪外部 API 调用吗?
- python - 在 Python 中查找并突出显示文本文件中拼写错误的单词(客户端-服务器模型)
- excel - 模糊客户姓名,
- ios - 切换标签时的活动指示器
- kubernetes - GKE 从 GCP 内部的私有存储库中提取图像
- bash - 管道 LHS 的输出是否成为管道 RHS 的 arg
- curl - gitlab-ci.yml 中的 curl 请求失败,但脚本应该运行