Linux内核是否仅使用旧版C90语法,还是已经优化为使用C99/C11特性?
我在想最新版本的C是否会尽可能被使用。
Linux内核是否仅使用旧版C90语法,还是已经优化为使用C99/C11特性?
我在想最新版本的C是否会尽可能被使用。
gcc -std=gnu11
进行编译,该编译器支持ISO C标准2011版的GNU方言。感谢marc-2377在his answer中发布了该文件的参考。内核是用C语言编写的。更准确地说,内核通常在
-std=gnu11
下使用gcc进行编译:ISO C11的GNU方言。clang也受支持,请参阅“使用Clang / LLVM构建Linux”的文档。
Linus Torvalds曾经表达过对C99引入的某些功能的不喜欢,比如混合声明和语句。当时内核是使用gcc -std=gnu89
编译的。我没有调查他的态度是否改变。但这只是编码风格的问题,而不是语言标准。
由于我的原始答案已经不再相关,我已删除了大部分内容。
-std=gnu11
[gcc-c-dialect-options]:ISO C11的GNU方言。
(它还表示支持Clang。)
gcc -std=gnu11
进行编译。 - Keith Thompson在检查为什么内核在22年后仍未要求C99时,我偶然发现了这个问题。内核中有一些部分使用C99,但这些部分都被#ifdef
包围。
无论如何,以下讨论(2021年9月)Linus与一些GCC人员之间的讨论提供了一些相关的背景,虽然它主要是关于标准规定的头文件包含(例如<stdint.h>
),而不是关于C语言功能的。
我认为这个线程的结束很遗憾,特别是C99-<stdint.h>
情况下的固定宽度整数类型将非常有帮助。
更一般地说,现在内核也支持使用Clang进行构建,将内核迁移到标准(我指的是ISO C)基线而不是GNU基础上,将是一件好事。而且一个超过20年的标准对于内核来说应该足够了,我个人认为...
寻找官方声明(或建议)允许在内核代码中使用哪个版本的C标准实际上是非常困难的。最接近的答案是内核的最低编译器要求是gcc 3.2,但这并没有解决问题。
然而,需要注意的是,指定初始化程序和“long long”(都是严格的C99)在整个内核代码和内核模块中广泛使用。因此,内核不会被编译为纯C89/C90。您绝对需要一个C99编译器(或者至少是带有这些内容的“非标准扩展”的C89编译器)。因此,内核是用C89编写的这一想法是绝对错误的。(可能还有其他C99功能,但我没有检查过。)
另一方面,内核代码的编码风格要求非常严格(这是通过程序检查的),据我所知,某些C99功能是不允许的(例如在代码中间声明变量或作为for循环参数)。我得到的印象是存在某种默认情况下以C89编写代码的隐含大部分未声明的原则,但是您可以使用这些少数的C99功能,但不能使用其他任何功能。
其实你的问题存在一些错误假设,所以并没有一个确切的答案。C 语言版本假定存在一个平台,但像 Linux 这样的操作系统内核本身就是一个平台(或者至少是其中的一个大部分),所以它们没有“版本”的概念。
就语言解析器的定义而言,Linux 是用当前并发的 gcc/icc 等支持的任何语言编写的,目前是 C99。但正如我所说,C90 和 C99 之间的差异基于内核和库,因此它们实际上并不适用于内核。(我只能想到一个例外,那就是匿名函数,内核不使用。)
你所了解的关于 C 的大多数日常事物实际上是来自库,这取决于内核。因此,当你编写内核时,你实际上正在处理与编写普通 C 程序时完全不同的设置。
long long
、混合声明和语句、_Bool
等等。至于你所说的“匿名函数”,我不确定你的意思;在C90、C99或C11中都没有这样的功能。 - Keith Thompson