主题:【分享-信盈达】Linux内核编码风格7!
第十二章:宏,列举(enum)和RTL
定义常量和列举里的标签的宏的名字需要大写。
#define CONSTANT 0x12345
在定义几个相关的常量时,最好用列举。
宏的名字请用大写字母,不过形如函数的宏的名字可以用小写字母。
一般的,如果能写成内联函数就不要写成像函数的宏。
含有多个语句的宏应该被包含在一个do-while代码块里:
#define macrofun(a, b, c) \
do
{ \
if (a == 5) \
do_this(b, c); \
} while
(0)
使用宏的时候应避免的事情:
1) 影响控制流程的宏:
#define FOO(x) \
do
{ \
if (blah(x) < 0)
\
return -EBUGGERED; \
}
while(0)
非常不好。它看起来像一个函数,不过却能导致“调用”它的函数退出;
don't break the internal parsers of those who will
read the code.
2) 依赖于一个固定名字的本地变量的宏:
#define FOO(val) bar(index, val)
可能看起来像是个不错的东西,不过它非常容易把读代码的人搞糊涂,而且容易导致看起来不相关的改动带来错误。
3) 作为左值的带参数的宏: FOO(x) = y;如果有人把FOO变成一个内联函数的话,这种用法就会出错了。
4) 忘记了优先级:使用表达式定义常量的宏必须将表达式置于一对小括号之内。带参数的宏也要注意此类问题。
#define CONSTANT 0x4000
#define CONSTEXP (CONSTANT | 3)
cpp手册对宏的讲解很详细。Gcc internals手册也详细讲解了RTL(译注:register
transfer language),内核里的汇编语言经常用到它。
第十三章:打印内核消息
内核开发者应该是受过良好教育的。请一定注意内核信息的拼写,以给人以好的印象。不要用不规范的单词比如“dont”,而要用“do not”或者“don't”。保证这些信息简单、
明了、无歧义。
内核信息不必以句点结束。
在小括号里打印数字(%d)没有任何价值,应该避免这样做。
<linux/device.h>里有一些驱动模型诊断宏,你应该使用它们,以确保信息对应于正确的设备和驱动,并且被标记了正确的消息级别。这些宏有:dev_err(), dev_warn(),
dev_info()等等。对于那些不和某个特定设备相关连的信息,<linux/kernel.h>定义了pr_debug()和pr_info()。
写出好的调试信息可以是一个很大的挑战;当你写出来之后,这些信息在远程除错的时候就会成为极大的帮助。当DEBUG符号没有被定义的时候,这些信息不应该被编译进内核里(也就是说,默认地,它们不应该被包含在内)。如果你使用dev_dbg()或者pr_debug(),就能自动达到这个效果。很多子系统拥有Kconfig选项来启用-DDEBUG。还有一个相关的惯例是使用VERBOSE_DEBUG来添加dev_vdbg()消息到那些已经由DEBUG启用的消息之上。