首页 > 解决方案 > 语言标准版本与编译器版本

问题描述

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,以便我可以利用某些宏。

标签: cgccstandardsversioningc99

解决方案


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


推荐阅读