哪个C版本在Linux内核中使用?

时间:2013-12-15 22:11:37

标签: linux-kernel

Linux内核是仅使用旧的C90语法还是使用C99 / C11功能进行了优化?

我想知道在可能的情况下是否使用了最新版本的C语言。

3 个答案:

答案 0 :(得分:45)

Linux kernel coding style文件对C90与C99的使用没有多大关系。

它建议将typedef用于"新类型,与标准C99类型相同,在某些特殊情况下"同时在大多数情况下阻止typedef。请注意,这并不意味着取决于C99标准,因为这样的typedef可以在纯C90中定义。

后来在讨论typedef时,它说:

  

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

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

对C99的唯一其他引用是:

  

评论的Linux风格是C89" / * ... * /"风格。
  不要使用C99风格的" // ......"评价。

顶级kernel documentation web page将C99标准称为C编程语言的当前版本" (编写时可能是正确的;目前的官方版本现在是C11)。

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

Linux内核的编码约定主要由Linus Torvalds控制。 2012年4月This message of his显示了他对(某些)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

Bandrami's answer 部分正确指出C99添加的许多功能都在库中。在大多数情况下,库功能与Linux内核无关。内核不会在托管的&#34;中运行。环境,它无法访问大多数C标准库;例如,您不能在内核中使用printf(这里有一个类似的printk函数用于记录和调试)。但这只是图片的一部分。 C99添加的许多功能都是正确的语言(即ISO C标准第6节描述的部分),并且至少可能适用于内核源代码。

更新:

RudolfW指出this commit,这使-std=gnu89配置(带有GNU扩展的C 89/90)明确。

  

最终结果:我们可能会升级到更新的stdc模型   最终,但现在新的模型有些烦人   缺点,所以传统的&#34; gnu89&#34;模特最终成为了   首选。

这是对gcc5的变化的回应,这显然会将默认标准更改为C11(我不知道那是-std=c11还是-std=gnu11,尽管我和# 34;如果不是后者,我会感到有点惊讶。)

答案 1 :(得分:1)

到目前为止,https://www.kernel.org/doc/html/latest/process/programming-language.html上的文档显示:

  

内核使用C编程语言[c-language]编写。更多   确切地说,内核通常使用gcc [gcc]在   -std = gnu89 [gcc-c-dialect-options]:ISO C90的GNU方言(包括某些C99功能)。

答案 2 :(得分:-8)

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

就解析器的语言定义而言,Linux是用并发的gcc / icc / etc编写的。将支持,截至目前是C99。但正如我所说,C90和C99之间的差异基于内核和库,所以它们并不真正适用于内核。 (我能想到的唯一例外是匿名函数,内核不使用它。)

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