Linux内核编程规范与代码风格

source: https://www.kernel.org/doc/html/latest/process/coding-style.html
translated by trav, travmymail@gmail.com

这是一篇阐述Linux内核编程代码风格的文档,译者以学习为目的进行翻译。

1 缩进

Tab的宽度是八个字符,因此缩进的宽度也是八个字符。有些异教徒想让缩进变成四个字符,甚至是两个字符的宽度,这些人和那些把 PI 定义为 3 的人是一个路子的。

注意:缩进的全部意义在于清晰地定义语句块的开始与结束,特别是当你盯着屏幕20个小时之后,你会发现长的缩进宽度的作用。

现在有些人说八个字符的宽度太宽了,这会让代码往右移很远,在一块八十字符宽的屏幕上,这样的代码会很难阅读。对此的回答是,如果你写的代码需要超过三层的缩进,那么你把一切都搞砸了,你应该修复你的程序。

简而言之,八个字符宽度的缩进让代码更容易阅读,并且额外的好处就是提醒你,不要在一个函数里写太多层的嵌套逻辑。请记住这个警示。

switch语句的缩进方式是让case与switch对齐:

switch (suffix) { case 'G': case 'g': mem <<= 30; break; case 'M': case 'm': mem <<= 20; break; case 'K': case 'k': mem <<= 10; /* fall through */ default: break; }

不要在单独一行里写多个语句,除非你想干什么不为人知的事:

if (condition) do_this; do_something_everytime;

对了,不要把多个赋值语句放在同一行,内核的代码风格是十分简洁的,请尽量避免使用复杂的表达式。

除了在注释、文档和Kconfig中,永远不要使用空格作为缩进,上面的例子是故意犯的错误。

找一个像样的编辑器,不要在行末留有空格。

2 换行

规范代码风格的目的是提高代码的可读性和维护性。

单行的宽度限制为八十列,这是强烈推荐的设置。

任何一行超过八十列宽度的语句都应该拆分成多个行,除非超过八十列的部分可以提高可读性且不会隐藏信息。拆分出来的子句长度总是应该比其主句要短,并且应该尽量靠右。这条法则同样适用于一个有很长的参数列表的函数头。然而,千万不要把用户可见的字符串,比如 printk 的信息,拆分成多行,因为这样会导致使用 grep 的时候找不到这些信息。

3 括号与空格

另一个关于 C 代码风格的议题就是大括号的位置。这个问题不像缩进那么具有技术性,我们并不能说某一种风格要在技术上优于另一种风格。但是我们更推荐的,就是有远见的 Kernighan 和 Ritchie 展示的方式,把左括号放在行末,把右括号放在行首:

if (x is true) { we do y }

这同样适用于其他非函数的语句块 (if, switch, for, while, do) :

switch (action) { case KOBJ_ADD: return "add"; case KOBJ_REMOVE: return "remove"; case KOBJ_CHANGE: return "change"; default: return NULL; }

然而,有一个特殊的例子,就是函数:函数的左括号应该放在行首:

int function(int x) { body of function }

异教徒们会认为这样的风格是不一致的,但是所有有脑子的人都知道尽管是 K&R 也是不一致的(译者注:K&R这本书的第一版和第二版有不一致的地方)。除此之外,我们知道函数是很特殊的,在 C 语言中,你不能有嵌套函数。

注意到,右括号一般是单独成一行的,除非右括号之后紧随着紧密结合的语句,例如 do-while 语句和 if 语句:

do { body of do-loop } while (condition);

以及

if (x == y) { .. } else if (x > y) { ... } else { .... }

依据:K&R

注意到,这种风格应该在不降低可读性的前提下尽可能减少空行的数量。想一想,在一块只有 25 行的屏幕上,无用的换行少了,那么就有更多的空行来写注释。

当单行语句可以解决的时候,不要使用没必要的括号:

if (condition) action();

以及

if (condition) do_this(); else do_that();

这一点不适用于只有一个 case 有单行,其他 case 有多行的情况:

if (condition) { do_this(); do_that(); } else { otherwise(); }

在一个循环中超过一个语句的情况也同样需要使用括号:

while (condition) { if (test) do_something(); }

3.1 空格

Linux 内核风格的空格主要用在一些关键字上,即在关键字之后添一个空格。值得关注的例外是一些长得像函数的关键字,比如:sizeof, typeof, alignof, attribute,在 Linux 中,这些关键字的使用都会带上一对括号,尽管在 C 语言的使用上并不需要带上括号。

所以在下面这些关键字之后添加一个空格:

if, switch, case, for, do, while

但是不要添加在 sizeof, typeof, alignof, attribute 之后:

s = sizeof(struct file);

不要在括号周围多此一举的添加空格,下面这个例子糟透了:

s = sizeof( struct file );

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wsfpsf.html