Linux内核是仅使用旧的C90语法还是使用C99/C11功能进行了优化?
我想知道是否尽可能使用最新版本的C.
在Linux内核编码风格的文档没有说太多关于使用C90的C99对比.
它建议使用typedef作为"在某些特殊情况下与标准C99类型相同的新类型",同时在大多数情况下阻止typedef.请注意,这实际上并不意味着取决于C99标准,因为这样的typedef可以在纯C90中定义.
稍后在讨论typedef时,它说:
在用户空间可见的某些结构中,我们不能要求C99类型,也不能使用
u32
上面的表格.因此,我们__u32
在与用户空间共享的所有结构中使用 和类似的类型.
这意味着内核必须使用用C90编写的用户代码.
对C99的唯一其他参考是:
评论的Linux风格是C89"/*...*/"风格.
不要使用C99风格的"// ..."注释.
顶级内核文档网页将C99标准称为"C编程语言的当前版本"(在编写时可能是正确的;当前的正式版本现在是C11).
查看内核源代码,Makefile
目录树中有1766个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
Bandrami的回答是部分地指出,许多由C99添加的功能是在图书馆正确.在大多数情况下,库功能与Linux内核无关.内核不在"托管"环境中运行,并且它无法访问大多数C标准库; 例如,你不能printf
在内核中使用(有一个类似的printk
函数用于记录和调试).但这只是图片的一部分.C99添加的许多功能都是正确的语言(即ISO C标准第6部分描述的部分),并且至少可能适用于内核源代码.
更新:
RudolfW指出了这个提交,它使-std=gnu89
配置(C 89/90与GNU扩展)明确.
最终结果:我们最终可能会升级到更新的stdc模型,但是现在新模型存在一些烦人的缺陷,因此传统的"gnu89"模型最终成为首选模型.
这是对gcc5的变化的回应,它显然将默认标准更改为C11(我不知道是否是,-std=c11
或者-std=gnu11
,如果不是后者,我会感到有点惊讶.)