Linux内核编码风格
Linus Torvalds
这是一篇描述linux 内核编码风格的短小文档。编码风格是个人化的,而且我不想将自己的意见强加在任何人身上,但是编码风格却和我必须要维护的东西是密切相关的。至少,你可以考虑这点的观点。
首先,我建议打印一份关于 GNU编码标准 的复印件。我并不期望你读,烧掉它吧,那只是一个标志性的雕塑。
不管怎么样,从这里开始:
第一章 :缩进
Tabs是 8 个字节,因此缩进也是 8 个字节。有一些邪恶的人试着将缩进改为 4 个字节(甚至是 2 个字节)的深度,那就象有些人试将 PI 的值定义为 3 一样。
理由:缩进背后隐藏的是清晰地定义一个控制块的开始和结束。特别是你将一直看着你的屏幕整整20 个小时,你会发现如果有一个大的缩进,那将会更容易,清晰的看到缩进是怎么样工作的。
现在有些人声称8 个字节的缩进会使得代码太靠右,那样我们在 80 字节的终端屏幕上阅读会很不轻松。对于这个问题的回答是,如果你需要 3 个层次以上的缩进( 2 , 4 , 8chars), 你只是将自己陷入更大的困境中,你会希望缩进是固定的。
简而言之,8 个字节的缩进让阅读变得更容易。而且你的代码的嵌套函数太深时,你会发现一个提醒你的额外好处。你应该听从那个提醒。
第二章 :花括号位置
另一个常常和C 风格相关的话题就是花括号的位置问题。不像缩进大小,在选择花括号位置策略时很少有技术性的理由,但是更希望的方式是由 Kernighan 和 Ritchie 首先提出来的,将开始花括号放在一行的结束位置,结束花括号放在一行的开始位置,因此:
If( x is true) {
We do y
}
然而,有一种特例,即命名函数:它们将开始花括号放在下一行的开始位置,因此:
int function(int x)
{
Body of function
}
世界上的邪恶的人们已经声称这种不一致性总是存在的,但是理智的人都认为K&R 是正确的。而且,函数是特俗的。(你不会在 C 中嵌套函数)
注意结束花括号是单独一行的,除了在以下一些情形下:(花括号后紧跟着继续阐述的相同语句)
do{
Body of do-loop
}while(condition)
And
If(x==y){
..
}else if(x>y) {
...
}else {
...
}
同样,注意花括号的放置可以减少空行的数目,而不会带来不可读性。因此,由于新行的提供不是可再生的资源(想想只有25 行的终端屏幕),你可以在更多的空行上标上自己的注释。
第三章 :命名
C是一个简朴的语言,你的命名也应该如此。与 Modula-2 和 Pascal 程序员不同, C 程序员不需要使用可爱的名字,像 ThisVariableIsATemporaryCounter. 。一个 C 语言程序员将称这个变量为 tmp ,便于书写,也不缺乏可读性。
然而,当大小写混合的名字使你不禁皱眉时,对于那些对全局变量进行描述的名字来说,采用大小写混合的方式是一种必须。把一个全局函数叫做foo 将会引来强烈滴攻击的。
将一个函数的类型编码成一个名字是需要费尽心思的。编译器知道函数的类型并且进行检查,但是那却会让一个程序员疑惑。微软会编写出一些具有漏洞的程序就不足为奇了。
本地变量应该简短到位。如果你需要一些随意的整型循环计数器,那可能可以叫做i 。把它叫做 loop_counter 是没有必要的,如果没有误解的可能性。类似的, tmp 可以是任意类型的变量,用于存储一个临时性的变量。
如果你害怕混淆本地变量的名字,你将会有另外一个问题,这个问题叫做函数增长荷尔蒙失调综合征。见下章。
第四章 函数
函数应该短小精炼,并且只做一件事情,并且做好。它们内容长短应该在一个屏幕或者两个屏幕。(ISO/ANSI 屏幕的大小是 80*24), 。
函数的最大长度和函数的复杂性以及函数缩进程度成反比例。因此,如果你有一个简单的函数,它可能只是一个case 语句,你需要做根据很多不同的情形做很多很小的事情。这样的函数可以是长的。
然而,如果你有一个复杂的函数,而且你怀疑缺乏天分的一年级高中学生可能不能理解这个函数的意思,那么你更加应该遵循最大长度限制的规则。使用带有描述名字的帮组函数.
另外一个量度函数的标准是局部变量的数目。变量不应该超过5-10 个,不然你会犯错误。重新构思函数,然后将这个函数分解成几个小的函数。一个人的大脑通常容易的记住大约 7 件不同的事情,更多的话,人就容易混淆起来。如果你觉得你聪明,那么你也许可以理解两周前你所作的事情。
第五章 :注释
注释是好的习惯,可过度注释也是一种危险。不要试着在注释中去去解释你的代码是怎么样实现的。把代码写下来,那么代码是如何实现的更明显,解释已经写下来的代码是浪费时间的。
通常,你要让你的注释告诉人们你的代码是做什么的,而不是如何。同样,避免把注释放在函数函数体内。如果函数很复杂,以至于你需要将在不同的位置进行注释,那么你应该先返回到第四章内(笔者意思是对复杂函数进行分解,拆分为几个小的函数)。你可以写一些小的注释来提醒和警告一些特别好的或者坏的代码,但是避免太多这样的注释。相反,把注释放在函数的前面,告诉人们这个函数是做什么的,如果可能,可以写上为什么这样做。
第六章 :Emacs 工具的使用
你可能已经从长期使用Linux 的用户那听说了 GNU emacs 编辑器可以自动地编排 C 源文件。而且你也确实注意到了那点。