Linux kernel Linux内核使用哪个C版本?

Linux kernel Linux内核使用哪个C版本?,linux-kernel,Linux Kernel,Linux内核是否只使用旧的C90语法,或者是否使用C99/C11特性进行了优化 我想知道,如果可能的话,是否会使用最新版本的C。没有真正的答案,因为你的问题做出了错误的假设。C语言版本假设存在一个平台,但是像Linux这样的操作系统内核是平台(或者至少是平台的很大一部分),所以他们没有这个意义上的“版本” 根据语法分析器对语言的定义,Linux是用并发gcc/icc/etc支持的任何语言编写的,到目前为止,它是C99。但正如我所说,C90和C99之间的差异是基于内核和库的,因此它们一开始并不真

Linux内核是否只使用旧的C90语法,或者是否使用C99/C11特性进行了优化


我想知道,如果可能的话,是否会使用最新版本的C。

没有真正的答案,因为你的问题做出了错误的假设。C语言版本假设存在一个平台,但是像Linux这样的操作系统内核是平台(或者至少是平台的很大一部分),所以他们没有这个意义上的“版本”

根据语法分析器对语言的定义,Linux是用并发gcc/icc/etc支持的任何语言编写的,到目前为止,它是C99。但正如我所说,C90和C99之间的差异是基于内核和库的,因此它们一开始并不真正适用于内核。(我能想到的唯一例外是匿名函数,内核不使用匿名函数。)

关于C的大多数日常知识实际上都来自于库,这取决于内核。因此,当您编写内核时,实际上您所处理的设置与编写普通C程序时大不相同

有关更新,请参见此答案的底部

该文档没有对C90与C99的使用做太多说明

它建议将typedef用于“在某些特殊情况下与标准C99类型相同的新类型”,同时在大多数情况下不鼓励使用typedef。注意,这实际上并不意味着依赖于C99标准,因为这样的typedef可以在纯C90中定义

在后面的typedefs讨论中,它说:

在用户空间可见的某些结构中,我们不能 需要C99类型,不能使用上面的
u32
表单。因此,我们使用
\uuu32
以及与共享的所有结构中的类似类型 用户空间

这意味着内核必须使用用C90编写的用户代码

C99的唯一其他参考是:

评论的Linux样式是C89“/*…*/”样式。
不要使用C99样式“/…”注释

顶层将C99标准称为“C编程语言的当前版本”(在编写时可能是正确的;当前的官方版本现在是C11)

查看内核源代码,目录树中有1766个
Makefile
s(上次我从git中检出时)。其中,只有3个引用了
-std=gnu99
gcc选项,这些是用于工具的,而不是用于主内核本身(还有2个引用了当前默认的
-std=gnu89
)。这意味着绝大多数Linux内核源代码都是使用选项编写的,这些选项使其(大部分)符合C89/C90标准,并带有一些特定于GNU的扩展。其中一些扩展是C99特性

Linux内核的编码约定主要由Linus Torvalds控制。从2012年4月开始,他对C99的(部分)特定功能表现出个人态度:

On Wed, Apr 11, 2012 at 9:28 PM, Oleg Nesterov <oleg@redhat.com> wrote:
>
> Agreed. But,
>
>        error: 'for' loop initial declaration used outside C99 mode
>
> we should change CFLAGS, I guess. BTW, personally I'd like very much
> to use "for (type var; ...")" if this was allowed.

The sad part is that if we allow that, we also get that *other* insane
C99 variable thing - mixing variables and code.

I *like* getting warnings for confused people who start introducing
variables in the middle of blocks of code. That's not well-contained
like the loop variable.

That said, most of the stuff in C99 are extensions that we used long
before C99, so I guess we might as well just add the stupid flag. And
discourage people from mixing declarations and code other ways (sparse
etc).

                         Linus
2012年4月11日星期三晚上9:28,Oleg Nesterov写道:
>
>同意。但是
>
>错误:“for”循环初始声明在C99模式之外使用
>
>我想我们应该换CFLAG。顺便说一句,我个人非常喜欢
>如果允许,则使用“for(type var;…)”。
可悲的是,如果我们允许这样做,我们也会让其他人变得疯狂
C99变量的东西-混合变量和代码。
我喜欢为那些开始介绍的困惑的人得到警告
代码块中间的变量。
就像循环变量一样。
也就是说,C99中的大部分内容都是我们长期使用的扩展
在C99之前,所以我想我们最好添加愚蠢的标志
阻止人们以其他方式混合声明和代码(稀疏
等等)。
莱纳斯
C99添加的许多功能都在库中,这一点在一定程度上是正确的。在大多数情况下,库功能与Linux内核无关。内核不在“托管”环境中运行,并且无法访问大多数C标准库;例如,您不能在内核中使用
printf
(有一个类似的
printk
函数用于日志记录和调试)。但这只是图片的一部分。C99添加的许多功能都是使用正确的语言(即ISO C标准第6节描述的部分),并且至少可能适用于内核源代码

更新:

RudolfW指出,这使得
-std=gnu89
配置(带有GNU扩展的C89/90)显式化

最终结果:我们可能会升级到一个更新的stdc模型 最终,但现在新型号有一些恼人的问题 因此,传统的“gnu89”模型最终成为 首选的

这是对gcc第5版更改的响应,该版本将默认标准选项从
-std=gnu90
更改为
-std=gnu11
(跳过
-std=gnu99
)。自2018年9月5日起,linux git repo中的顶级
Makefile
仍然指
-std=gnu89
。(
-std=gnu89
-std-gnu90
是等效的。)


引用了可能更直接相关的内容。它明确指出“内核通常是在
-std=gnu89
下使用gcc编译的。”

截至目前,位于

内核是用C语言编写的 确切地说,内核通常是在 -std=gnu89:ISO C90的GNU方言(包括一些C99特性)


这是不正确的。C90和C99之间有许多语言变化,例如可变长度数组、
long-long
、混合声明和语句、
\u Bool
,等等。我不知道你说的“匿名函数”是什么意思;C90、C99或C11中没有这种功能。@Keith你能回答一下吗