Linux 内核代码风格

您所在的位置:网站首页 读大专可以转专业吗 Linux 内核代码风格

Linux 内核代码风格

2023-11-21 23:53| 来源: 网络整理| 查看: 265

Linux 内核代码风格¶

这是一个简短的文档,描述了 linux 内核的首选代码风格。代码风格是因人而异的, 而且我不愿意把自己的观点强加给任何人,但这就像我去做任何事情都必须遵循的原则 那样,我也希望在绝大多数事上保持这种的态度。请 (在写代码时) 至少考虑一下这里 的代码风格。

首先,我建议你打印一份 GNU 代码规范,然后不要读。烧了它,这是一个具有重大象征 性意义的动作。

不管怎样,现在我们开始:

1) 缩进¶

制表符是 8 个字符,所以缩进也是 8 个字符。有些异端运动试图将缩进变为 4 (甚至 2!) 字符深,这几乎相当于尝试将圆周率的值定义为 3。

理由:缩进的全部意义就在于清楚的定义一个控制块起止于何处。尤其是当你盯着你的 屏幕连续看了 20 小时之后,你将会发现大一点的缩进会使你更容易分辨缩进。

现在,有些人会抱怨 8 个字符的缩进会使代码向右边移动的太远,在 80 个字符的终端 屏幕上就很难读这样的代码。这个问题的答案是,如果你需要 3 级以上的缩进,不管用 何种方式你的代码已经有问题了,应该修正你的程序。

简而言之,8 个字符的缩进可以让代码更容易阅读,还有一个好处是当你的函数嵌套太 深的时候可以给你警告。留心这个警告。

在 switch 语句中消除多级缩进的首选的方式是让 switch 和从属于它的 case 标签对齐于同一列,而不要 两次缩进 case 标签。比如:

switch (suffix) { case 'G': case 'g': mem f))

还有可以做严格的类型检查的 min() 和 max() 宏,如果你需要可以使用它们。你可以 自己看看那个头文件里还定义了什么你可以拿来用的东西,如果有定义的话,你就不应 在你的代码里自己重新定义。

18) 编辑器模式行和其他需要罗嗦的事情¶

有一些编辑器可以解释嵌入在源文件里的由一些特殊标记标明的配置信息。比如,emacs 能够解释被标记成这样的行:

-*- mode: c -*-

或者这样的:

/* Local Variables: compile-command: "gcc -DMAGIC_DEBUG_FLAG foo.c" End: */

Vim 能够解释这样的标记:

/* vim:set sw=8 noet */

不要在源代码中包含任何这样的内容。每个人都有他自己的编辑器配置,你的源文件不 应该覆盖别人的配置。这包括有关缩进和模式配置的标记。人们可以使用他们自己定制 的模式,或者使用其他可以产生正确的缩进的巧妙方法。

19) 内联汇编¶

在特定架构的代码中,你可能需要内联汇编与 CPU 和平台相关功能连接。需要这么做时 就不要犹豫。然而,当 C 可以完成工作时,不要平白无故地使用内联汇编。在可能的情 况下,你可以并且应该用 C 和硬件沟通。

请考虑去写捆绑通用位元 (wrap common bits) 的内联汇编的简单辅助函数,别去重复 地写下只有细微差异内联汇编。记住内联汇编可以使用 C 参数。

大型,有一定复杂度的汇编函数应该放在 .S 文件内,用相应的 C 原型定义在 C 头文 件中。汇编函数的 C 原型应该使用 asmlinkage 。

你可能需要把汇编语句标记为 volatile,用来阻止 GCC 在没发现任何副作用后就把它 移除了。你不必总是这样做,尽管,这不必要的举动会限制优化。

在写一个包含多条指令的单个内联汇编语句时,把每条指令用引号分割而且各占一行, 除了最后一条指令外,在每个指令结尾加上 nt,让汇编输出时可以正确地缩进下一条 指令:

asm ("magic %reg1, #42\n\t" "more_magic %reg2, %reg3" : /* outputs */ : /* inputs */ : /* clobbers */); 20) 条件编译¶

只要可能,就不要在 .c 文件里面使用预处理条件 (#if, #ifdef);这样做让代码更难 阅读并且更难去跟踪逻辑。替代方案是,在头文件中用预处理条件提供给那些 .c 文件 使用,再给 #else 提供一个空桩 (no-op stub) 版本,然后在 .c 文件内无条件地调用 那些 (定义在头文件内的) 函数。这样做,编译器会避免为桩函数 (stub) 的调用生成 任何代码,产生的结果是相同的,但逻辑将更加清晰。

最好倾向于编译整个函数,而不是函数的一部分或表达式的一部分。与其放一个 ifdef 在表达式内,不如分解出部分或全部表达式,放进一个单独的辅助函数,并应用预处理 条件到这个辅助函数内。

如果你有一个在特定配置中,可能变成未使用的函数或变量,编译器会警告它定义了但 未使用,把它标记为 __maybe_unused 而不是将它包含在一个预处理条件中。(然而,如 果一个函数或变量总是未使用,就直接删除它。)

在代码中,尽可能地使用 IS_ENABLED 宏来转化某个 Kconfig 标记为 C 的布尔 表达式,并在一般的 C 条件中使用它:

if (IS_ENABLED(CONFIG_SOMETHING)) { ... }

编译器会做常量折叠,然后就像使用 #ifdef 那样去包含或排除代码块,所以这不会带 来任何运行时开销。然而,这种方法依旧允许 C 编译器查看块内的代码,并检查它的正 确性 (语法,类型,符号引用,等等)。因此,如果条件不满足,代码块内的引用符号就 不存在时,你还是必须去用 #ifdef。

在任何有意义的 #if 或 #ifdef 块的末尾 (超过几行的),在 #endif 同一行的后面写下 注解,注释这个条件表达式。例如:

#ifdef CONFIG_SOMETHING ... #endif /* CONFIG_SOMETHING */ 附录 I) 参考¶

The C Programming Language, 第二版 作者:Brian W. Kernighan 和 Denni M. Ritchie. Prentice Hall, Inc., 1988. ISBN 0-13-110362-8 (软皮), 0-13-110370-9 (硬皮).

The Practice of Programming 作者:Brian W. Kernighan 和 Rob Pike. Addison-Wesley, Inc., 1999. ISBN 0-201-61586-X.

GNU 手册 - 遵循 K&R 标准和此文本 - cpp, gcc, gcc internals and indent, 都可以从 http://www.gnu.org/manual/ 找到

WG14 是 C 语言的国际标准化工作组,URL: http://www.open-std.org/JTC1/SC22/WG14/

Kernel process/coding-style.rst,作者 [email protected] 发表于 OLS 2002: http://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3