C、C99、ANSI C 和 GNU C 有啥区别?
Posted
技术标签:
【中文标题】C、C99、ANSI C 和 GNU C 有啥区别?【英文标题】:What is the difference between C, C99, ANSI C and GNU C?C、C99、ANSI C 和 GNU C 有什么区别? 【发布时间】:2013-06-16 21:25:05 【问题描述】:我已经开始在codechef 上进行编程练习,并且对C 和C99 之间的差异感到困惑。这里的 C 是什么意思?是 C89 吗? 查看this submit 底部的语言。它同时包含 C 和 C99。
我在互联网上找到了一个叫做 GNU C 的东西。对于 linux/unix 系统有不同的 C 吗?这些是否符合 ANSI 的 C 标准?我还在某些地方读过“C99 严格”。这是什么?
还有其他不同的 C 标准在使用吗?有什么叫 C 4.3.2 还是当前使用的 gcc 版本?
编辑:
This、This、This 提供帮助。我将进行更多搜索并编辑未答复的内容。
我不是编程新手。我知道C语言是什么。我知道 ANSI 有不同的 C 标准,例如 C89、C99 和 C11。
【问题讨论】:
别忘了POSIX C :-) 【参考方案1】:标准化之前的一切通常被称为“K&R C”,以著名的书籍(1st edition 和2nd edition)命名,C 语言的发明者 Dennis Ritchie 作为作者之一。这就是 1972-1989 年间的“C 语言”。
第一个 C 标准于 1989 年由美国国家标准协会 ANSI 在美国全国发布。此版本称为 C89 或 ANSI-C。从 1989 年到 1990 年,这是“C 语言”。
次年,美国标准在国际上被接受并由 ISO (ISO 9899:1990) 发布。此版本称为 C90。从技术上讲,它与 C89/ANSI-C 标准相同。形式上,它取代了 C89/ANSI-C,使它们过时了。从 1990 年到 1999 年,C90 是“C 语言”。
请注意,自 1989 年以来,ANSI 与 C 语言没有任何关系。仍在谈论“ANSI C”的程序员通常不知道它的含义。 ISO 通过标准 ISO 9899“拥有”C 语言。
1995 年发布了一个小更新,有时称为“C95”。这不是重大修订,而是正式命名为 ISO/IEC 9899:1990/Amd.1:1995 的技术修订。主要变化是引入了宽字符支持。
1999 年,C 标准进行了一次重大修订 (ISO 9899:1999)。此版本的标准称为 C99。从 1999 年到 2011 年,这是“C 语言”。
2011 年,C 标准再次更改(ISO 9899:2011)。此版本称为 C11。语言中添加了各种新功能,如_Generic
、_Static_assert
和线程支持。该更新非常关注多核、多处理和表达测序。从 2011 年到 2017 年,这是“C 语言”。
2017年修改C11,解决各种缺陷报告。该标准非正式地称为 C17 或 C18。它于 2017 年完成(并使用 __STDC_VERSION__
= 201710L
),但被 ISO 发布为 9899:2018,因此 C17/C18 之间存在歧义。它不包含新功能,只是更正。它是 C 语言的当前版本。
“C99 严格”可能是指编译器设置强制编译器严格遵守标准。 C 标准中有一个术语一致的实现。本质上它的意思是:“这个编译器实际上正确地实现了 C 语言”。正确实现 C 语言的程序被正式称为严格符合程序。
“GNU C”可能意味着两件事。作为 GNU 编译器集合 (GCC) 的一部分的 C 编译器本身。或者它可能意味着 GCC C 编译器使用的非标准默认设置。如果您使用gcc program.c
编译,那么您不会根据 C 标准进行编译,而是根据非标准 GNU 设置进行编译,这可能被称为“GNU C”。例如,整个 Linux 内核是用非标准 GNU C 制作的,而不是标准 C。
如果你想根据 C 标准编译你的程序,你应该输入gcc -std=c99 -pedantic-errors
。如果您的 GCC 版本支持,请将 c99 替换为 c11。
【讨论】:
严格的编译器设置可能意味着“禁用扩展;仅使用标准定义的 C 语言”以及或超过“正确编译”。接受语言的扩展是完全正确的;该标准被定义为允许这样做。 还有 C94/C95 修正案 1,主要增加了更广泛的字符支持。另请参阅List of Standard Header Files in C and C++。 您写道,从 C90 到 C99 发生了很多变化。你能说出几个吗? @Lundin 你为 K&R 链接了错误的书;这是描述 C89 标准的第二版。 是的,但关键是那不是定义 C 编程语言的版本。并不是说它会在任何地方出售。【参考方案2】:我必须对 ANSI C 做出回应。虽然 ANSI 没有对它做任何事情,但编译器仍然是基于它构建的。 PIC XC16 编译器例如: “编译器是经过充分验证的编译器,符合 ANSI C 由 ANSI 规范 (ANSI x3.159-1989) 定义的标准和 在 Kernighan 和 Ritchie 的 C 编程语言(第二 版)。 ……” 并非所有编程都适用于 PC 等“大型”计算机。为您的设备成本编写编译器,并验证成本时间和美元。 ANSI C 活得很好& 生活在您的嵌入式/实时设备中。
【讨论】:
此外,如果要对使用 20 年历史的编译器构建的嵌入式项目进行维护,通常最好继续使用有 20 年历史的编译器而不是使用更新的版本,即使可以升级,除非在旧版本的编译器中发现了严重的错误并在以后的版本中修复。 如果编译器供应商从使用专有编译器设计切换到基于 clang 的编译器设计,并且只有基于 clang 的编译器支持 C11 功能,那么这将是支持将自己限制在以下功能的有力论据由健壮的旧编译器支持,而不是更“现代”的编译器。【参考方案3】:ANSI C: 第一种 C 语言在 1989 年被称为 ANSI 的机构标准化,这就是它被称为 c89 的原因。
C99 : 随着开发者需求的需求,在1999-2000年C99中加入了更多或额外的关键字和特性(例如:inline、boolean..增加了浮点算术库函数)
GNU C:GNU 是一个类似于 unix 的操作系统 (www.gnu.org) 并且 GNU 的项目需要基于 ANSI C 标准的 C 编程语言。 GNU 使用 GCC(GNU Compiler Collection)编译器来编译代码。它具有定义系统调用的 C 库函数,例如 malloc、calloc、exit...等
ANSI C 是被其他标准使用或引用的标准。
【讨论】:
关于 C99 严格以及 codechef 中的 C 是 C89 还是更早的非标准化原始 C 的任何信息 更正:ANSI C 是一个过时的标准,只有过时的文档才会引用它。 C 语言称为 ISO C,或者如果您将 ISO/IEC 9899:2011 称为。【参考方案4】:除了伦丁Answer
这是丹尼斯·里奇在被问及Say 时必须回答的问题
“为什么 K&R 在编写 K&R 第 2 版之前不等到最终批准的 ANSI 标准?”
为什么 K&R 不等到最终批准的 ANSI 标准再编写 K&R第二版?看来这本书只会成为正确的标准 几个月后它将被最终的 ANSI 标准取代。我知道 在这个后期阶段可能几乎没有重大变化,但为什么不呢? 等待几个月,确保你得到它 100% 正确,而不是需要 几乎立即写出第 3 版还是过时了?
我们认为庆祝 10 周年会很好 的第一版。 更严重的是,我们去年夏天开始工作,因为我们有 那时的时间和倾向,似乎X3J11正在逼近 结束。在 12 月和 1 月,当我们完成时,我们考虑了 重要变化的可能性是否值得推迟 交付,以及(在与出版商讨论此事后) 决定不值得等待。 P-H 想要它,而且两者都有 布赖恩和我想把它排除在我们的议程之外。
即使标准有变化,也很难想象 他们将足够广泛以保证新版本。 (我们甚至准备好以某种方式应对 noalias,如果它持续的话。) 我们已准备好在未来的印刷中进行必要的更改, 但有理由希望它们应该是次要的。 X3J11的 成员们也非常渴望在不令人惊讶的情况下完成; 他们中的许多人为准备 ANSI 编译器的公司工作, 毕竟。
丹尼斯·里奇
【讨论】:
太糟糕了 Dennis Ritchie 没有意识到如何使用别名规则来暗示编译器不应该任何努力识别有用的别名形式,而是认为代码被迟钝的编译器破坏的程序员应该“感谢”编译器向他们展示他们的代码是“有缺陷的”——否则他本可以告诉推动此类规则的人们明确表示拒绝支持超出标准最低要求的别名将使编译器不适合某些用途,低级代码需要别名也不是缺陷。 @supercat 我其实不明白别名规则是什么意思,你能帮帮我吗? 最初的概念是像int i; int test(double *p) i=1; *p=2.0; return i;
这样的给定代码,在写入*p
之后,不应该要求编译器重新加载i
,因为p
可能持有地址的i
。完全合理。问题是现代编译器使用相同的规则来证明写入long*
不会影响long long
的假设是正确的,即使两种类型具有相同的大小和表示,甚至如果两个结构共享一个公共初始序列,代码将永远不会使用一种类型的指针来读取通过另一种类型写入的 CIS 成员。【参考方案5】:
这个问题没有在网上彻底搜索答案,你可以看看这个:
-
C 是一种通用编程语言,最初由
1969 年至 1973 年间,Dennis Ritchie 在 AT&T 贝尔实验室工作。
C99 是由 ISO 发布并在 1999 年左右被 ANSI 采用的 C 语言标准。
GNU C 只是 c89 的扩展,同时也增加了 c99 的一些特性,但总体上它与 c99 标准不同,所以在 gcc 中编译时我们必须输入
-std=c99
,这在其他答案中已经提到.
ANSI C 是 ANSI 发布的一系列标准。
【讨论】:
我现在在网上搜索。我编辑了这个问题。在发布问题之前,我了解 C 和 ANSI 标准。我对具体的事情感到困惑。我会尽量准确一点。 关于 C99 严格以及 codechef 中的 C 是 C89 还是更早的非标准化原始 C 的任何信息 这个答案包含很多错误。 C99是ISO在1999年左右定义的标准。C语言在国际上已经标准化了23年。因此 ANSI 与它无关,他们已经 24 年没有触及 C 标准了。如今,他们只是为美国市场印刷和分发 ISO 标准。 @Lundin 哦!!是的,实际上我写了“定义”,但事实并非如此,它应该在那里“采用”。我进行了更正,ANSI 早在 1989 年就发布了第一个 C 标准,该标准被 ISO 采用。之后几乎所有标准由 ISO 发布并被 ANSI 采用,并且答案很简短,所以我只提到了一些保持答案简短的事情。 请注意gcc
支持-std=c89
和-std=gnu89
和-std=c99
和-std=gnu99
(并且足够现代的版本支持-std=c11
和-std=gnu11
)。不同之处在于标准 C 上的扩展自动可用或仅当源代码促使编译器为它们提供适当的宏(例如 -D_XOPEN_SOURCE=700
)时才可用。以上是关于C、C99、ANSI C 和 GNU C 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章