第十六章:函数返回值及命名
函数可以返回很多种不同类型的值,最常见的一种是表明函数执行成功或者失败的值。这样的一个值可以表示为一个错误代码整数(-E**=失败,0=成功)或者一个“成功”布尔值(0=失败,非0=成功)。
混合使用这两种表达方式是难于发现的bug的来源。如果C语言本身严格区分整形和布尔型变量,那么编译器就能够帮我们发现这些错误……不过C语言不区分。为了避免产生这种bug,请遵循下面的惯例:
如果函数的名字是一个动作或者强制性的命令,那么这个函数应该返回错误代码
整数。如果是一个判断,那么函数应该返回一个“成功”布尔值。
比如,“add work”是一个命令,所以add_work()函数在成功时返回0,在失败时返回
-EBUSY。类似的,因为“PCI device present”是一个判断,所pci_dev_present()函数在成功找到一个匹配的设备时应该返回1,如果找不到时应该返回0。
所有导出(译注:EXPORT)的函数都必须遵守这个惯例,所有的公共函数也都应该如此。私有(static)函数不需要如此,但是我们也推荐这样做。
返回值是实际计算结果而不是计算是否成功的标志的函数不受此惯例的限制。一般的,他们通过返回一些正常值范围之外的结果来表示出错。典型的例子是返回指针的函数,他们使用NULL或者ERR_PTR机制来报告错误。
第十七章:不要重新发明内核宏
头文件include/linux/kernel.h包含了一些宏,你应该使用它们,而不要自己写一些它们的变种。比如,如果你需要计算一个数组的长度,使用这个宏
#defineARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
类似的,如果你要计算某结构体成员的大小,使用
#defineFIELD_SIZEOF(t, f) (sizeof(((t*)0)->f))
还有可以做严格的类型检查的min()和max()宏,如果你需要可以使用它们。你可以自己看看那个头文件里还定义了什么你可以拿来用的东西,如果有定义的话,你就不应在你的代码里自己重新定义。
第十八章:编辑器模式行和其他需要罗嗦的事情
有一些编辑器可以解释嵌入在源文件里的由一些特殊标记标明的配置信息。比如,emacs能够解释被标记成这样的行:
-*- mode: c -*-
或者这样的:
/*
Local Variables:
compile-command: "gcc -DMAGIC_DEBUG_FLAGfoo.c"
End:
*/
Vim能够解释这样的标记:
/* vim:set sw=8 noet */
不要在源代码中包含任何这样的内容。每个人都有他自己的编辑器配置,你的源文件不应该覆盖别人的配置。这包括有关缩进和模式配置的标记。人们可以使用他们自己定制的模式,或者使用其他可以产生正确的缩进的巧妙方法。