Linux内核使用的C语言版本是哪个?

50

Linux内核是否仅使用旧版C90语法,还是已经优化为使用C99/C11特性?

我在想最新版本的C是否会尽可能被使用。

5个回答

66
截至2022年9月19日,Linux内核通常使用gcc -std=gnu11进行编译,该编译器支持ISO C标准2011版的GNU方言。
参考资料:https://www.kernel.org/doc/html/latest/process/programming-language.html

内核是用C语言编写的。更准确地说,内核通常在-std=gnu11下使用gcc进行编译:ISO C11的GNU方言。clang也受支持,请参阅“使用Clang / LLVM构建Linux”的文档。

感谢marc-2377his answer中发布了该文件的参考。

Linus Torvalds曾经表达过对C99引入的某些功能的不喜欢,比如混合声明和语句。当时内核是使用gcc -std=gnu89编译的。我没有调查他的态度是否改变。但这只是编码风格的问题,而不是语言标准。

由于我的原始答案已经不再相关,我已删除了大部分内容。


2
请参考此提交记录 - 现在他们明确使用带有GNU扩展的C90,因为立即转换到C99/C11可能不会产生完全可靠的结果。 - RudolfW
这个答案似乎不是最新的。请查看Marc的答案 https://dev59.com/dmIj5IYBdhLWcg3wHh3_#58313785 - Acorn
@Acorn,它怎么不是最新的?(在您发表评论之后,但在我看到它之前,我编辑了最后一段,但我相信它已经是最新和正确的。Marc的答案确实添加了一个链接到我以前没有见过的文档。) - Keith Thompson
1
@KeithThompson 这已经过时了,因为那个文档似乎是新的,所以这个答案之前是可以的。 - Acorn
如果有人感兴趣,我在下面添加了一个答案,其中引用了最近的LKML讨论,广泛涉及此主题。 - Axel
显示剩余3条评论

14

该文档现在指出内核通常使用gcc -std=gnu11进行编译。 - Keith Thompson
@KeithThompson 很酷,谢谢你让我知道了 - 我已经更新了我的答案。 - Marc.2377

1

在检查为什么内核在22年后仍未要求C99时,我偶然发现了这个问题。内核中有一些部分使用C99,但这些部分都被#ifdef包围。

无论如何,以下讨论(2021年9月)Linus与一些GCC人员之间的讨论提供了一些相关的背景,虽然它主要是关于标准规定的头文件包含(例如<stdint.h>),而不是关于C语言功能的。

我认为这个线程的结束很遗憾,特别是C99-<stdint.h>情况下的固定宽度整数类型将非常有帮助。

更一般地说,现在内核也支持使用Clang进行构建,将内核迁移到标准(我指的是ISO C)基线而不是GNU基础上,将是一件好事。而且一个超过20年的标准对于内核来说应该足够了,我个人认为...


从Linux 5.18开始,现在需要C11。 - Axel

0

寻找官方声明(或建议)允许在内核代码中使用哪个版本的C标准实际上是非常困难的。最接近的答案是内核的最低编译器要求是gcc 3.2,但这并没有解决问题。

然而,需要注意的是,指定初始化程序和“long long”(都是严格的C99)在整个内核代码和内核模块中广泛使用。因此,内核不会被编译为纯C89/C90。您绝对需要一个C99编译器(或者至少是带有这些内容的“非标准扩展”的C89编译器)。因此,内核是用C89编写的这一想法是绝对错误的。(可能还有其他C99功能,但我没有检查过。)

另一方面,内核代码的编码风格要求非常严格(这是通过程序检查的),据我所知,某些C99功能是不允许的(例如在代码中间声明变量或作为for循环参数)。我得到的印象是存在某种默认情况下以C89编写代码的隐含大部分未声明的原则,但是您可以使用这些少数的C99功能,但不能使用其他任何功能。


-11

其实你的问题存在一些错误假设,所以并没有一个确切的答案。C 语言版本假定存在一个平台,但像 Linux 这样的操作系统内核本身就是一个平台(或者至少是其中的一个大部分),所以它们没有“版本”的概念。

就语言解析器的定义而言,Linux 是用当前并发的 gcc/icc 等支持的任何语言编写的,目前是 C99。但正如我所说,C90 和 C99 之间的差异基于内核和库,因此它们实际上并不适用于内核。(我只能想到一个例外,那就是匿名函数,内核不使用。)

你所了解的关于 C 的大多数日常事物实际上是来自库,这取决于内核。因此,当你编写内核时,你实际上正在处理与编写普通 C 程序时完全不同的设置。


6
那是错误的。C90和C99之间存在许多语言上的差异,例如可变长度数组、long long、混合声明和语句、_Bool等等。至于你所说的“匿名函数”,我不确定你的意思;在C90、C99或C11中都没有这样的功能。 - Keith Thompson
@Keith,你能回答我的问题吗? - user2686744
@Keith,内核必须自己打字,因为所有这些“语言”特性都是在库中实现的,而不是编译器(有时间检查源代码树中的typedefs)。是的,我想到的匿名函数是gcc扩展;糟糕。 - Bandrami
3
这个库中没有实现我提到的任何功能,它们也不是类型定义。 - Keith Thompson
6
这是错误和误导性的。C90和C99之间有很多差异,与标准库无关。此外,标准不依赖于“平台”。它描述语法和抽象语义。 Linux也并非完全使用C99编写的,因为它依赖于相当多的非标准GNU扩展。 - user529758

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接