Linux内核编码风格(二)

Chapter 6: Functions第6章 函数Functions should be short and sweet, and do just one thing. They shouldfit on one or two screenfuls of text (the ISO/ANSI screen size is 80×24,as we all know), and do one thing and do that well.函数应该简短而漂亮,并且只做一件事。函数应该可以一屏或者两屏显示完(我们都知道ISO/ANSI屏幕大小是80×24),只做一件事情,并把它做好。The maximum length of a function is inversely proportional to thecomplexity and indentation level of that function. So, if you have aconceptually simple function that is just one long (but simple)case-statement, where you have to do lots of small things for a lot ofdifferent cases, it’s OK to have a longer function.一个函数的最大长度是和该函数的复杂度和缩进级数成反比的。所以,如果你有一个理论上很简单的只有一个很长(但是简单)的case语句的函数,而且你需要在每个case里做很多很小的事情,这样的函数尽管很长,但也是可以的。

However, if you have a complex function, and you suspect that aless-than-gifted first-year high-school student might not evenunderstand what the function is all about, you should adhere to themaximum limits all the more closely. Use helper functions withdescriptive names (you can ask the compiler to in-line them if you thinkit’s performance-critical, and it will probably do a better job of itthan you would have done).

不过,如果你有一个复杂的函数,而且你怀疑一个天分不是很高的高中一年级学生可能都搞不清楚这个函数的目的,你应该严格的遵守前面提到的长度限制。使用辅助函数,并为之取个具描述性的名字(如果你觉得它们的性能很重要的话,可以让编译器内联它们,这样的效果往往会比你写一个复杂函数的效果要好。)

Another measure of the function is the number of local variables. Theyshouldn’t exceed 5-10, or you’re doing something wrong. Re-think thefunction, and split it into smaller pieces. A human brain cangenerally easily keep track of about 7 different things, anything moreand it gets confused. You know you’re brilliant, but maybe you’d like to understand what you did 2 weeks from now.函数的另外一个衡量标准是局部变量的数目,它们不应超过5-10个,否则你的函数就有问题了。重新考虑一下你的函数,把它分拆成更小的函数。人的大脑一般可以轻松的同时跟踪7个不同的事物,如果再增加的话,就会糊涂了。即便你聪颖过人,你也可能会记不清你2个星期前做过的事情。In source files, separate functions with one blank line. If the function isexported, the EXPORT* macro for it should follow immediately after the closingfunction brace line. E.g.:在源文件里,使用空行隔开不同的函数。如果该函数需要被导出,它的EXPORT*宏应该紧贴在它的结束大括号之下。比如:int system_is_up(void){return system_state == SYSTEM_RUNNING;}EXPORT_SYMBOL(system_is_up);In function prototypes, include parameter names with their data types.Although this is not required by the C language, it is preferred in Linuxbecause it is a simple way to add valuable information for the reader.在函数原型中,包含函数名和它们的数据类型。虽然C语言里没有这样的要求,在Linux里这是提倡的做法,因为这样可以很简单的给读者提供更多的有价值的信息。Chapter 7: Centralized exiting of functions第7章 集中的函数退出途径Albeit deprecated by some people, the equivalent of the goto statement isused frequently by compilers in form of the unconditional jump instruction.虽然被某些人声称已经过时,但是goto语句的等价物还是经常被编译器以无条件跳转指令的形式使用。The goto statement comes in handy when a function exits from multiple locations and some common work such as cleanup has to be done.当一个函数从多个位置退出并且需要做一些通用的清理工作的时,使用goto就很方便。The rationale is:- unconditional statements are easier to understand and follow- nesting is reduced- errors by not updating individual exit points when makingmodifications are prevented- saves the compiler work to optimize redundant code away ;)理由是:- 无条件语句容易理解和跟踪- 嵌套程度减小- 可以避免修改时由于忘记更新某个单独的退出点而导致的错误- 减轻了编译器的工作,无需删除冗余代码;int fun(int a){int result = 0;char *buffer = kmalloc(SIZE);if (buffer == NULL)return -ENOMEM;if (condition1) {while (loop1) {…}result = 1;goto out;}…out:kfree(buffer);return result;

}

Chapter 8: Commenting第8章 注释Comments are good, but there is also a danger of over-commenting. NEVER try to explain HOW your code works in a comment: it’s much better to write the code so that the _working_ is obvious, and it’s a waste of time to explain badly written code.注释是好的,不过有过度注释的危险。永远不要在注释里解释你的代码是如何运作的:更好的做法是让别人一看你的代码就可以明白,解释写的很差的代码是浪费时间。Generally, you want your comments to tell WHAT your code does, not HOW. Also, try to avoid putting comments inside a function body: if the function is so complex that you need to separately comment parts of it, you should probably go back to chapter 6 for a while. You can make small comments to note or warn about something particularly clever (or ugly), but try to avoid excess. Instead, put the comments at the head of the function, telling people what it does, and possibly WHY it does it.一般的,你的注释应该告诉别人你的代码做了什么,而不是怎么做的。也请你不要把注释放在一个函数体内部:如果函数复杂到你需要独立的注释其中的一部分,你很可能需要回到第六章看一看。你可以做一些小注释来注明或警告某些很聪明(或者槽糕)的做法,但不要加太多。你应该做的,是把注释放在函数的头部,告诉人们它做了什么,也可以加上它做这些事情的原因。When commenting the kernel API functions, please use the kernel-doc format. See the files Documentation/kernel-doc-nano-HOWTO.txt and scripts/kernel-doc for details.当注释内核API函数时,请使用kernel-doc格式。请看Documentation/kernel-doc-nano-HOWTO.txt和scripts/kernel-doc以获得详细信息。Linux style for comments is the C89 "/* … */" style. Don’t use C99-style "// …" comments.Linux的注释风格是C89“/* … */”风格。不要使用C99风格“// …”注释。The preferred style for long (multi-line) comments is:长(多行)的首选注释风格是:/** This is the preferred style for multi-line* comments in the Linux kernel source code.* Please use it consistently.** Description: A column of asterisks on the left side,* with beginning and ending almost-blank lines.*/It’s also important to comment data, whether they are basic types or derived types. To this end, use just one data declaration per line (no commas for multiple data declarations). This leaves you room for a small comment on each item, explaining its use.注释数据也是很重要的,不管是基本类型还是衍生类型。为了方便实现这一点,每一行应只声明一个数据(不要使用逗号来一次声明多个数据)。这样你就有空间来为每个数据写一段小注释来解释它们的用途了。Chapter 9: You’ve made a mess of it第9章 你已经把事情弄糟了That’s OK, we all do. You’ve probably been told by your long-time Unix user helper that "GNU emacs" automatically formats the C sources for you, and you’ve noticed that yes, it does do that, but the defaults it uses are less than desirable (in fact, they are worse than random typing – an infinite number of monkeys typing into GNU emacs would never make a good program).这没什么,我们都是这样。可能你的使用了很长时间Unix的朋友已经告诉你“GNU emacs”能自动帮你格式化C源代码,而且你也注意到了,确实是这样,不过它所使用的默认值和我们想要的相去甚远(实际上,甚至比随机打的还要差——无数个猴子在GNU emacs里打字永远不会创造出一个好程序)。So, you can either get rid of GNU emacs, or change it to use saner values. To do the latter, you can stick the following in your .emacs file:所以你要么放弃GNU emacs,要么改变它以使它使用更合理的设定。要采用后一个方案,你可以把下面这段粘贴到你的.emacs文件里。(defun c-lineup-arglist-tabs-only (ignored)"Line up argument lists by tabs, not spaces"(let* ((anchor (c-langelem-pos c-syntactic-element))(column (c-langelem-2nd-pos c-syntactic-element))(offset (- (1+ column) anchor))(steps (floor offset c-basic-offset))) (* (max steps 1) c-basic-offset)))(add-hook ‘c-mode-common-hook (lambda () ;; Add kernel style (c-add-style "linux-tabs-only" ‘("linux" (c-offsets-alist (arglist-cont-nonempty c-lineup-gcc-asm-reg c-lineup-arglist-tabs-only))))))(add-hook ‘c-mode-hook (lambda () (let ((filename (buffer-file-name))) ;; Enable kernel mode for the appropriate files (when (and filename (string-match (expand-file-name "~/src/linux-trees") filename)) (setq indent-tabs-mode t) (c-set-style "linux-tabs-only")))))This will make emacs go better with the kernel coding style for C files below ~/src/linux-trees.这将使emacs为~/src/linux-trees下的C文件使用内核编码风格。But even if you fail in getting emacs to do sane formatting, noteverything is lost: use "indent".不过,就算你让emacs正确地格式化的尝试失败了,也并不意味着你失去了一切:还可以用“indent”。Now, again, GNU indent has the same brain-dead settings that GNU emacs has, which is why you need to give it a few command line options. However, that’s not too bad, because even the makers of GNU indent recognize the authority of K&R (the GNU people aren’t evil, they are just severely misguided in this matter), so you just give indent the options "-kr -i8" (stands for "K&R, 8 character indents"), or use "scripts/Lindent", which indents in the latest style.不过,GNU indent也有和GNU emacs一样有问题的设定,所以你需要给它一些命令选项。不过,这还不算太糟糕,因为就算是GNU indent的作者也认同K&R的权威性(GNU的人并不是坏人,他们只是在这个问题上被严重的误导了),所以你只要给indent指定选项“-kr -i8”(代表“K&R,8个字符缩进”),或者使用“scripts/Lindent”,这样就可以以最时髦的方式缩进源代码。"indent" has a lot of options, and especially when it comes to comment re-formatting you may want to take a look at the man page. But remember: "indent" is not a fix for bad rogramming.“indent”有很多选项,特别是重新格式化注释的时候,你可能需要看一下它的手册页。不过记住:“indent”不能修正坏的编程习惯。

Chapter 10: Kconfig configuration files第10章 Kconfig配置文件For all of the Kconfig* configuration files throughout the source tree,the indentation is somewhat different. Lines under a "config" definitionare indented with one tab, while help text is indented an additional twospaces. Example:对于遍布源码树的所有Kconfig*配置文件来说,它们缩进方式与C代码相比有所不同。紧挨在“config”定义下面的行缩进一个制表符,帮助信息则再多缩进2个空格。比如:config AUDITbool "Auditing support"depends on NEThelpEnable auditing infrastructure that can be used with anotherkernel subsystem, such as SELinux (which requires this forlogging of avc messages output). Does not do system-callauditing without CONFIG_AUDITSYSCALL.Features that might still be considered unstable should be defined asdependent on "EXPERIMENTAL":仍然被认为不够稳定的功能应该被定义为依赖于“EXPERIMENTAL”:config SLUBdepends on EXPERIMENTAL && !ARCH_USES_SLAB_PAGE_STRUCTbool "SLUB (Unqueued Allocator)"…while seriously dangerous features (such as write support for certainfilesystems) should advertise this prominently in their prompt string:而那些危险的功能(比如某些文件系统的写支持)应该在它们的提示字符串里显著的声明这一点:config ADFS_FS_RWbool "ADFS write support (DANGEROUS)"depends on ADFS_FS…For full documentation on the configuration files, see the fileDocumentation/kbuild/kconfig-language.txt.要查看配置文件的完整文档,请看Documentation/kbuild/kconfig-language.txt。

人生就像爬坡,要一步一步来。

Linux内核编码风格(二)

相关文章:

你感兴趣的文章:

标签云: