“ C”标准是否指定编译器必须遵循的标准?

时间:2018-08-18 19:10:03

标签: c gcc standards

我刚尝试使用GNU编译器4.9.2版编译C程序。源代码包含一些for int i=0; ...语句,编译器给我一个错误,并指出我应该使用-std=c99来编译 for循环初始声明。显然,此类声明在C99之前无效。

在另一台机器上,我有一个更新的GNU编译器(8.1.1),可以在不显式指定-std=c99的情况下编译相同的源代码。

由于GNU显然使他们的编译器C99在4.9.2和8.1.1之间兼容,这使我想到一个问题,即最新的C标准是否指定编译器必须遵守C99(或其他标准)。

3 个答案:

答案 0 :(得分:4)

自愿选择是否遵循C标准或其特定版本。选择不是来自C标准。它来自外面。任何执行C的人都将决定是否符合2018 C标准(或大部分但不完全符合),是否符合2011 C标准,是否符合C的“ K&R”概念或其他要求。 C标准中没有任何内容说明,如果您符合该标准,则您的编译器必须符合某些以前的版本。在您选择符合标准之前,该标准实际上无法要求您执行任何操作。

C标准及其制定者和认可并发布它的标准组织几乎没有权力使任何人做任何事情。他们无法发布C标准,并说您René Nyffenegger必须遵守2018 C标准。它们不是立法机构。私人方之间有合同,其中说某些项目将根据该标准或该标准进行生产,但这些合同是私人协议,而不是公法。

在2018 C标准中,前言第8段说:

  

为解释标准的自愿性质,与合格评定有关的ISO特定术语和表达的含义,以及有关ISO在贸易技术壁垒(TBT)中遵守世界贸易组织(WTO)原则的信息),请参见以下URL:www.iso.org/iso/foreword.html

标准组织也不能禁止您编写符合或不符合该标准任何特定版本的C编译器,也不能禁止您编写基本但不完全符合的编译器。

如果您在商业上使用C标准的名称,也许是声称符合标准,那么标准组织在这方面可能拥有一些合法权利。这涉及国际法和许多管辖区的法律,我不能权威地说。我还没有听说有人声称自己符合C标准。

发布新版本的标准时,标准组织确实会正式撤消标准的旧版本。这不会阻止您编写符合旧版本的C实现,但是会阻止您声明不符合旧版本的情况。 (例如,如果您同意的一项合同要求您遵守当前的C标准,则当组织发布新版本并撤回旧版本时,这种情况将会改变。)

答案 1 :(得分:1)

在GCC 5.0之前,它遵循(最紧密地)遵循的默认标准是C90标准-不指定标准等同于指定-std=gnu90

从5.0开始,默认设置已更改为C11标准-因此,不指定任何标准都等同于指定-std=gnu11

您的两个编译器版本都显示了此行为。

请注意,C标准仅规定编译器必须执行哪些操作才能遵守该标准。它不要求编译器相对于该标准的先前版本或将来版本进行操作。就该标准而言,该标准只有一个版本。编译器实现对其他版本的处理完全取决于编译器作者。

您当然可以使用显式版本覆盖GCC的默认行为:

  • -ansi
  • -std=c90
  • -std=c99
  • -std=c11
  • -std=gnu90
  • -std=gnu99
  • -std=gnu11
  • ...和其他一些变化...

-ansi选项等效于-std=c90-std=cXX-std=gnuXX之间的区别在于c版本没有为各种扩展名设置宏,因此您可能必须明确指出要使用POSIX接口,例如例如,使用-D_XOPEN_SOURCE=700等选项,而使用gnu版本则自动设置这些宏。

答案 2 :(得分:0)

每个C标准版本将实现分为两类:符合该标准特定版本的实现和不符合该特定版本的实现。没有任何C语言警察会打破任何出售不合格实施的人的膝盖。确实,在某些情况下,不合格的实现比任何合格的实现都要有用(例如,在某些小型嵌入式平台上,产生“ printf”的完全合格的实现所需的代码量可能会超过总代码可用空间)。此外,不能保证每个符合标准的实现都适用于任何特定目的(实际上,可以证明不适合任何目的的C实现,除非证明C标准并未规定有用性)。

大多数高质量的C开发系统都可以以不同的方式调用,这些方式可能符合(或不符合)该标准的不同版本,并且可能适合(或不适合)各种目的。从标准的角度来看,可以调用开发系统的每种不同模式都是不同的实现。我认为,将标准基于实现对流行功能或支持的支持(或缺乏),对实现进行子分类将是有用的,这些保证或保证会使实现适合(或不适合)用于常见目的(例如,低级或系统编程)但到目前为止,标准还没有这样做。