1efd298e4SAlex Shi.. include:: ../disclaimer-zh_CN.rst
2aa3b3690SAlex Shi
3*54156734SWu XiangCheng:Original: Documentation/process/coding-style.rst
4aa3b3690SAlex Shi
5efd298e4SAlex Shi.. _cn_codingstyle:
6aa3b3690SAlex Shi
7*54156734SWu XiangCheng:译者:
8*54156734SWu XiangCheng - 张乐 Zhang Le <r0bertz@gentoo.org>
9*54156734SWu XiangCheng - Andy Deng <theandy.deng@gmail.com>
10*54156734SWu XiangCheng - 吴想成 <bobwxc@email.cn>
11aa3b3690SAlex Shi
12*54156734SWu XiangCheng:校译:
13*54156734SWu XiangCheng - 王聪 Wang Cong <xiyou.wangcong@gmail.com>
14*54156734SWu XiangCheng - wheelz <kernel.zeng@gmail.com>
15*54156734SWu XiangCheng - 管旭东 Xudong Guan <xudong.guan@gmail.com>
16*54156734SWu XiangCheng - Li Zefan <lizf@cn.fujitsu.com>
17*54156734SWu XiangCheng - Wang Chen <wangchen@cn.fujitsu.com>
18aa3b3690SAlex Shi
19aa3b3690SAlex ShiLinux 内核代码风格
20*54156734SWu XiangCheng==================
21aa3b3690SAlex Shi
22aa3b3690SAlex Shi这是一个简短的文档,描述了 linux 内核的首选代码风格。代码风格是因人而异的,
23aa3b3690SAlex Shi而且我不愿意把自己的观点强加给任何人,但这就像我去做任何事情都必须遵循的原则
24aa3b3690SAlex Shi那样,我也希望在绝大多数事上保持这种的态度。请 (在写代码时) 至少考虑一下这里
25aa3b3690SAlex Shi的代码风格。
26aa3b3690SAlex Shi
27aa3b3690SAlex Shi首先,我建议你打印一份 GNU 代码规范,然后不要读。烧了它,这是一个具有重大象征
28aa3b3690SAlex Shi性意义的动作。
29aa3b3690SAlex Shi
30aa3b3690SAlex Shi不管怎样,现在我们开始:
31aa3b3690SAlex Shi
32aa3b3690SAlex Shi
33aa3b3690SAlex Shi1) 缩进
34*54156734SWu XiangCheng-------
35aa3b3690SAlex Shi
36aa3b3690SAlex Shi制表符是 8 个字符,所以缩进也是 8 个字符。有些异端运动试图将缩进变为 4 (甚至
37aa3b3690SAlex Shi2!) 字符深,这几乎相当于尝试将圆周率的值定义为 3。
38aa3b3690SAlex Shi
39aa3b3690SAlex Shi理由:缩进的全部意义就在于清楚的定义一个控制块起止于何处。尤其是当你盯着你的
40aa3b3690SAlex Shi屏幕连续看了 20 小时之后,你将会发现大一点的缩进会使你更容易分辨缩进。
41aa3b3690SAlex Shi
42aa3b3690SAlex Shi现在,有些人会抱怨 8 个字符的缩进会使代码向右边移动的太远,在 80 个字符的终端
43aa3b3690SAlex Shi屏幕上就很难读这样的代码。这个问题的答案是,如果你需要 3 级以上的缩进,不管用
44aa3b3690SAlex Shi何种方式你的代码已经有问题了,应该修正你的程序。
45aa3b3690SAlex Shi
46aa3b3690SAlex Shi简而言之,8 个字符的缩进可以让代码更容易阅读,还有一个好处是当你的函数嵌套太
47aa3b3690SAlex Shi深的时候可以给你警告。留心这个警告。
48aa3b3690SAlex Shi
49aa3b3690SAlex Shi在 switch 语句中消除多级缩进的首选的方式是让 ``switch`` 和从属于它的 ``case``
50aa3b3690SAlex Shi标签对齐于同一列,而不要 ``两次缩进`` ``case`` 标签。比如:
51aa3b3690SAlex Shi
52aa3b3690SAlex Shi.. code-block:: c
53aa3b3690SAlex Shi
54aa3b3690SAlex Shi	switch (suffix) {
55aa3b3690SAlex Shi	case 'G':
56aa3b3690SAlex Shi	case 'g':
57aa3b3690SAlex Shi		mem <<= 30;
58aa3b3690SAlex Shi		break;
59aa3b3690SAlex Shi	case 'M':
60aa3b3690SAlex Shi	case 'm':
61aa3b3690SAlex Shi		mem <<= 20;
62aa3b3690SAlex Shi		break;
63aa3b3690SAlex Shi	case 'K':
64aa3b3690SAlex Shi	case 'k':
65aa3b3690SAlex Shi		mem <<= 10;
66cc3496bfSWei Ming Chen		fallthrough;
67aa3b3690SAlex Shi	default:
68aa3b3690SAlex Shi		break;
69aa3b3690SAlex Shi	}
70aa3b3690SAlex Shi
71aa3b3690SAlex Shi不要把多个语句放在一行里,除非你有什么东西要隐藏:
72aa3b3690SAlex Shi
73aa3b3690SAlex Shi.. code-block:: c
74aa3b3690SAlex Shi
75aa3b3690SAlex Shi	if (condition) do_this;
76aa3b3690SAlex Shi	  do_something_everytime;
77aa3b3690SAlex Shi
78*54156734SWu XiangCheng不要使用逗号来避免使用大括号:
79*54156734SWu XiangCheng
80*54156734SWu XiangCheng.. code-block:: c
81*54156734SWu XiangCheng
82*54156734SWu XiangCheng	if (condition)
83*54156734SWu XiangCheng		do_this(), do_that();
84*54156734SWu XiangCheng
85*54156734SWu XiangCheng使用大括号包裹多语句:
86*54156734SWu XiangCheng
87*54156734SWu XiangCheng.. code-block:: c
88*54156734SWu XiangCheng
89*54156734SWu XiangCheng	if (condition) {
90*54156734SWu XiangCheng		do_this();
91*54156734SWu XiangCheng		do_that();
92*54156734SWu XiangCheng	}
93*54156734SWu XiangCheng
94aa3b3690SAlex Shi也不要在一行里放多个赋值语句。内核代码风格超级简单。就是避免可能导致别人误读
95aa3b3690SAlex Shi的表达式。
96aa3b3690SAlex Shi
97aa3b3690SAlex Shi除了注释、文档和 Kconfig 之外,不要使用空格来缩进,前面的例子是例外,是有意为
98aa3b3690SAlex Shi之。
99aa3b3690SAlex Shi
100aa3b3690SAlex Shi选用一个好的编辑器,不要在行尾留空格。
101aa3b3690SAlex Shi
102aa3b3690SAlex Shi
103aa3b3690SAlex Shi2) 把长的行和字符串打散
104*54156734SWu XiangCheng-----------------------
105aa3b3690SAlex Shi
106aa3b3690SAlex Shi代码风格的意义就在于使用平常使用的工具来维持代码的可读性和可维护性。
107aa3b3690SAlex Shi
108aa3b3690SAlex Shi每一行的长度的限制是 80 列,我们强烈建议您遵守这个惯例。
109aa3b3690SAlex Shi
110aa3b3690SAlex Shi长于 80 列的语句要打散成有意义的片段。除非超过 80 列能显著增加可读性,并且不
111*54156734SWu XiangCheng会隐藏信息。
112*54156734SWu XiangCheng
113*54156734SWu XiangCheng子片段要明显短于母片段,并明显靠右。一种非常常用的样式是将子体与函数左括号对齐。
114*54156734SWu XiangCheng
115*54156734SWu XiangCheng这同样适用于有着很长参数列表的函数头。
116*54156734SWu XiangCheng
117*54156734SWu XiangCheng然而,绝对不要打散对用户可见的字符串,例如 printk 信息,因为这样就
118aa3b3690SAlex Shi很难对它们 grep。
119aa3b3690SAlex Shi
120aa3b3690SAlex Shi
121aa3b3690SAlex Shi3) 大括号和空格的放置
122*54156734SWu XiangCheng---------------------
123aa3b3690SAlex Shi
124aa3b3690SAlex ShiC 语言风格中另外一个常见问题是大括号的放置。和缩进大小不同,选择或弃用某种放
125aa3b3690SAlex Shi置策略并没有多少技术上的原因,不过首选的方式,就像 Kernighan 和 Ritchie 展示
126aa3b3690SAlex Shi给我们的,是把起始大括号放在行尾,而把结束大括号放在行首,所以:
127aa3b3690SAlex Shi
128aa3b3690SAlex Shi.. code-block:: c
129aa3b3690SAlex Shi
130aa3b3690SAlex Shi	if (x is true) {
131aa3b3690SAlex Shi		we do y
132aa3b3690SAlex Shi	}
133aa3b3690SAlex Shi
134aa3b3690SAlex Shi这适用于所有的非函数语句块 (if, switch, for, while, do)。比如:
135aa3b3690SAlex Shi
136aa3b3690SAlex Shi.. code-block:: c
137aa3b3690SAlex Shi
138aa3b3690SAlex Shi	switch (action) {
139aa3b3690SAlex Shi	case KOBJ_ADD:
140aa3b3690SAlex Shi		return "add";
141aa3b3690SAlex Shi	case KOBJ_REMOVE:
142aa3b3690SAlex Shi		return "remove";
143aa3b3690SAlex Shi	case KOBJ_CHANGE:
144aa3b3690SAlex Shi		return "change";
145aa3b3690SAlex Shi	default:
146aa3b3690SAlex Shi		return NULL;
147aa3b3690SAlex Shi	}
148aa3b3690SAlex Shi
149aa3b3690SAlex Shi不过,有一个例外,那就是函数:函数的起始大括号放置于下一行的开头,所以:
150aa3b3690SAlex Shi
151aa3b3690SAlex Shi.. code-block:: c
152aa3b3690SAlex Shi
153aa3b3690SAlex Shi	int function(int x)
154aa3b3690SAlex Shi	{
155aa3b3690SAlex Shi		body of function
156aa3b3690SAlex Shi	}
157aa3b3690SAlex Shi
158*54156734SWu XiangCheng全世界的异端可能会抱怨这个不一致性是……呃……不一致,不过所有思维健全的人
159aa3b3690SAlex Shi都知道 (a) K&R 是 **正确的** 并且 (b) K&R 是正确的。此外,不管怎样函数都是特
160aa3b3690SAlex Shi殊的 (C 函数是不能嵌套的)。
161aa3b3690SAlex Shi
162aa3b3690SAlex Shi注意结束大括号独自占据一行,除非它后面跟着同一个语句的剩余部分,也就是 do 语
163*54156734SWu XiangCheng句中的 ``while`` 或者 if 语句中的 ``else`` ,像这样:
164aa3b3690SAlex Shi
165aa3b3690SAlex Shi.. code-block:: c
166aa3b3690SAlex Shi
167aa3b3690SAlex Shi	do {
168aa3b3690SAlex Shi		body of do-loop
169aa3b3690SAlex Shi	} while (condition);
170aa3b3690SAlex Shi
171aa3b3690SAlex Shi172aa3b3690SAlex Shi
173aa3b3690SAlex Shi.. code-block:: c
174aa3b3690SAlex Shi
175aa3b3690SAlex Shi	if (x == y) {
176aa3b3690SAlex Shi		..
177aa3b3690SAlex Shi	} else if (x > y) {
178aa3b3690SAlex Shi		...
179aa3b3690SAlex Shi	} else {
180aa3b3690SAlex Shi		....
181aa3b3690SAlex Shi	}
182aa3b3690SAlex Shi
183aa3b3690SAlex Shi理由:K&R。
184aa3b3690SAlex Shi
185aa3b3690SAlex Shi也请注意这种大括号的放置方式也能使空 (或者差不多空的) 行的数量最小化,同时不
186aa3b3690SAlex Shi失可读性。因此,由于你的屏幕上的新行是不可再生资源 (想想 25 行的终端屏幕),你
187aa3b3690SAlex Shi将会有更多的空行来放置注释。
188aa3b3690SAlex Shi
189aa3b3690SAlex Shi当只有一个单独的语句的时候,不用加不必要的大括号。
190aa3b3690SAlex Shi
191aa3b3690SAlex Shi.. code-block:: c
192aa3b3690SAlex Shi
193aa3b3690SAlex Shi	if (condition)
194aa3b3690SAlex Shi		action();
195aa3b3690SAlex Shi
196aa3b3690SAlex Shi197aa3b3690SAlex Shi
198aa3b3690SAlex Shi.. code-block:: c
199aa3b3690SAlex Shi
200aa3b3690SAlex Shi	if (condition)
201aa3b3690SAlex Shi		do_this();
202aa3b3690SAlex Shi	else
203aa3b3690SAlex Shi		do_that();
204aa3b3690SAlex Shi
205aa3b3690SAlex Shi这并不适用于只有一个条件分支是单语句的情况;这时所有分支都要使用大括号:
206aa3b3690SAlex Shi
207aa3b3690SAlex Shi.. code-block:: c
208aa3b3690SAlex Shi
209aa3b3690SAlex Shi	if (condition) {
210aa3b3690SAlex Shi		do_this();
211aa3b3690SAlex Shi		do_that();
212aa3b3690SAlex Shi	} else {
213aa3b3690SAlex Shi		otherwise();
214aa3b3690SAlex Shi	}
215aa3b3690SAlex Shi
216aa3b3690SAlex Shi3.1) 空格
217*54156734SWu XiangCheng*********
218aa3b3690SAlex Shi
219aa3b3690SAlex ShiLinux 内核的空格使用方式 (主要) 取决于它是用于函数还是关键字。(大多数) 关键字
220aa3b3690SAlex Shi后要加一个空格。值得注意的例外是 sizeof, typeof, alignof 和 __attribute__,这
221aa3b3690SAlex Shi些关键字某些程度上看起来更像函数 (它们在 Linux 里也常常伴随小括号而使用,尽管
222aa3b3690SAlex Shi在 C 里这样的小括号不是必需的,就像 ``struct fileinfo info;`` 声明过后的
223aa3b3690SAlex Shi``sizeof info``)。
224aa3b3690SAlex Shi
225aa3b3690SAlex Shi所以在这些关键字之后放一个空格::
226aa3b3690SAlex Shi
227aa3b3690SAlex Shi	if, switch, case, for, do, while
228aa3b3690SAlex Shi
229aa3b3690SAlex Shi但是不要在 sizeof, typeof, alignof 或者 __attribute__ 这些关键字之后放空格。
230aa3b3690SAlex Shi例如,
231aa3b3690SAlex Shi
232aa3b3690SAlex Shi.. code-block:: c
233aa3b3690SAlex Shi
234aa3b3690SAlex Shi	s = sizeof(struct file);
235aa3b3690SAlex Shi
236aa3b3690SAlex Shi不要在小括号里的表达式两侧加空格。这是一个 **反例** :
237aa3b3690SAlex Shi
238aa3b3690SAlex Shi.. code-block:: c
239aa3b3690SAlex Shi
240aa3b3690SAlex Shi	s = sizeof( struct file );
241aa3b3690SAlex Shi
242aa3b3690SAlex Shi当声明指针类型或者返回指针类型的函数时, ``*`` 的首选使用方式是使之靠近变量名
243aa3b3690SAlex Shi或者函数名,而不是靠近类型名。例子:
244aa3b3690SAlex Shi
245aa3b3690SAlex Shi.. code-block:: c
246aa3b3690SAlex Shi
247aa3b3690SAlex Shi	char *linux_banner;
248aa3b3690SAlex Shi	unsigned long long memparse(char *ptr, char **retptr);
249aa3b3690SAlex Shi	char *match_strdup(substring_t *s);
250aa3b3690SAlex Shi
251aa3b3690SAlex Shi在大多数二元和三元操作符两侧使用一个空格,例如下面所有这些操作符::
252aa3b3690SAlex Shi
253aa3b3690SAlex Shi	=  +  -  <  >  *  /  %  |  &  ^  <=  >=  ==  !=  ?  :
254aa3b3690SAlex Shi
255aa3b3690SAlex Shi但是一元操作符后不要加空格::
256aa3b3690SAlex Shi
257aa3b3690SAlex Shi	&  *  +  -  ~  !  sizeof  typeof  alignof  __attribute__  defined
258aa3b3690SAlex Shi
259aa3b3690SAlex Shi后缀自加和自减一元操作符前不加空格::
260aa3b3690SAlex Shi
261aa3b3690SAlex Shi	++  --
262aa3b3690SAlex Shi
263aa3b3690SAlex Shi前缀自加和自减一元操作符后不加空格::
264aa3b3690SAlex Shi
265aa3b3690SAlex Shi	++  --
266aa3b3690SAlex Shi
267aa3b3690SAlex Shi``.`` 和 ``->`` 结构体成员操作符前后不加空格。
268aa3b3690SAlex Shi
269aa3b3690SAlex Shi不要在行尾留空白。有些可以自动缩进的编辑器会在新行的行首加入适量的空白,然后
270aa3b3690SAlex Shi你就可以直接在那一行输入代码。不过假如你最后没有在那一行输入代码,有些编辑器
271aa3b3690SAlex Shi就不会移除已经加入的空白,就像你故意留下一个只有空白的行。包含行尾空白的行就
272aa3b3690SAlex Shi这样产生了。
273aa3b3690SAlex Shi
274aa3b3690SAlex Shi当 git 发现补丁包含了行尾空白的时候会警告你,并且可以应你的要求去掉行尾空白;
275aa3b3690SAlex Shi不过如果你是正在打一系列补丁,这样做会导致后面的补丁失败,因为你改变了补丁的
276aa3b3690SAlex Shi上下文。
277aa3b3690SAlex Shi
278aa3b3690SAlex Shi
279aa3b3690SAlex Shi4) 命名
280*54156734SWu XiangCheng-------
281aa3b3690SAlex Shi
282aa3b3690SAlex ShiC 是一个简朴的语言,你的命名也应该这样。和 Modula-2 和 Pascal 程序员不同,
283aa3b3690SAlex ShiC 程序员不使用类似 ThisVariableIsATemporaryCounter 这样华丽的名字。C 程序员会
284aa3b3690SAlex Shi称那个变量为 ``tmp`` ,这样写起来会更容易,而且至少不会令其难于理解。
285aa3b3690SAlex Shi
286aa3b3690SAlex Shi不过,虽然混用大小写的名字是不提倡使用的,但是全局变量还是需要一个具描述性的
287aa3b3690SAlex Shi名字。称一个全局函数为 ``foo`` 是一个难以饶恕的错误。
288aa3b3690SAlex Shi
289aa3b3690SAlex Shi全局变量 (只有当你 **真正** 需要它们的时候再用它) 需要有一个具描述性的名字,就
290aa3b3690SAlex Shi像全局函数。如果你有一个可以计算活动用户数量的函数,你应该叫它
291aa3b3690SAlex Shi``count_active_users()`` 或者类似的名字,你不应该叫它 ``cntuser()`` 。
292aa3b3690SAlex Shi
293aa3b3690SAlex Shi在函数名中包含函数类型 (所谓的匈牙利命名法) 是脑子出了问题——编译器知道那些类
294341968c6SHu Jialun型而且能够检查那些类型,这样做只能把程序员弄糊涂了。
295aa3b3690SAlex Shi
296aa3b3690SAlex Shi本地变量名应该简短,而且能够表达相关的含义。如果你有一些随机的整数型的循环计
297aa3b3690SAlex Shi数器,它应该被称为 ``i`` 。叫它 ``loop_counter`` 并无益处,如果它没有被误解的
298aa3b3690SAlex Shi可能的话。类似的, ``tmp`` 可以用来称呼任意类型的临时变量。
299aa3b3690SAlex Shi
300aa3b3690SAlex Shi如果你怕混淆了你的本地变量名,你就遇到另一个问题了,叫做函数增长荷尔蒙失衡综
301*54156734SWu XiangCheng合征。请看第六章 (函数)。
302aa3b3690SAlex Shi
303*54156734SWu XiangCheng对于符号名称和文档,避免引入新的“master/slave”(或独立于“master”的“slave”)
304*54156734SWu XiangCheng和“blacklist/whitelist”。
305*54156734SWu XiangCheng
306*54156734SWu XiangChengmaster/slave”推荐替换为:
307*54156734SWu XiangCheng    '{primary,main} / {secondary,replica,subordinate}'
308*54156734SWu XiangCheng    '{initiator,requester} / {target,responder}'
309*54156734SWu XiangCheng    '{controller,host} / {device,worker,proxy}'
310*54156734SWu XiangCheng    'leader/follower'
311*54156734SWu XiangCheng    'director/performer'
312*54156734SWu XiangCheng
313*54156734SWu XiangChengblacklist/whitelist”推荐替换为:
314*54156734SWu XiangCheng    'denylist/allowlist'
315*54156734SWu XiangCheng    'blocklist/passlist'
316*54156734SWu XiangCheng
317*54156734SWu XiangCheng引入新用法的例外情况是:维护用户空间ABI/API,或更新现有(截至2020年)硬件或
318*54156734SWu XiangCheng协议规范的代码时要求这些术语。对于新规范,尽可能将术语的规范用法转换为内核
319*54156734SWu XiangCheng编码标准。
320*54156734SWu XiangCheng
321*54156734SWu XiangCheng.. warning::
322*54156734SWu XiangCheng	以上主从、黑白名单规则不适用于中文文档,请勿更改中文术语!
323aa3b3690SAlex Shi
324aa3b3690SAlex Shi5) Typedef
325*54156734SWu XiangCheng----------
326aa3b3690SAlex Shi
327aa3b3690SAlex Shi不要使用类似 ``vps_t`` 之类的东西。
328aa3b3690SAlex Shi
329aa3b3690SAlex Shi对结构体和指针使用 typedef 是一个 **错误** 。当你在代码里看到:
330aa3b3690SAlex Shi
331aa3b3690SAlex Shi.. code-block:: c
332aa3b3690SAlex Shi
333aa3b3690SAlex Shi	vps_t a;
334aa3b3690SAlex Shi
335aa3b3690SAlex Shi这代表什么意思呢?
336aa3b3690SAlex Shi
337aa3b3690SAlex Shi相反,如果是这样
338aa3b3690SAlex Shi
339aa3b3690SAlex Shi.. code-block:: c
340aa3b3690SAlex Shi
341aa3b3690SAlex Shi	struct virtual_container *a;
342aa3b3690SAlex Shi
343aa3b3690SAlex Shi你就知道 ``a`` 是什么了。
344aa3b3690SAlex Shi
345aa3b3690SAlex Shi很多人认为 typedef ``能提高可读性`` 。实际不是这样的。它们只在下列情况下有用:
346aa3b3690SAlex Shi
347aa3b3690SAlex Shi (a) 完全不透明的对象 (这种情况下要主动使用 typedef 来 **隐藏** 这个对象实际上
348aa3b3690SAlex Shi     是什么)。
349aa3b3690SAlex Shi
350aa3b3690SAlex Shi     例如: ``pte_t`` 等不透明对象,你只能用合适的访问函数来访问它们。
351aa3b3690SAlex Shi
352aa3b3690SAlex Shi     .. note::
353aa3b3690SAlex Shi
354*54156734SWu XiangCheng       不透明性和“访问函数”本身是不好的。我们使用 pte_t 等类型的原因在于真
355aa3b3690SAlex Shi       的是完全没有任何共用的可访问信息。
356aa3b3690SAlex Shi
357aa3b3690SAlex Shi (b) 清楚的整数类型,如此,这层抽象就可以 **帮助** 消除到底是 ``int`` 还是
358aa3b3690SAlex Shi     ``long`` 的混淆。
359aa3b3690SAlex Shi
360aa3b3690SAlex Shi     u8/u16/u32 是完全没有问题的 typedef,不过它们更符合类别 (d) 而不是这里。
361aa3b3690SAlex Shi
362aa3b3690SAlex Shi     .. note::
363aa3b3690SAlex Shi
364aa3b3690SAlex Shi       要这样做,必须事出有因。如果某个变量是 ``unsigned long`` ,那么没有必要
365aa3b3690SAlex Shi
366aa3b3690SAlex Shi	typedef unsigned long myflags_t;
367aa3b3690SAlex Shi
368aa3b3690SAlex Shi     不过如果有一个明确的原因,比如它在某种情况下可能会是一个 ``unsigned int``
369aa3b3690SAlex Shi     而在其他情况下可能为 ``unsigned long`` ,那么就不要犹豫,请务必使用
370aa3b3690SAlex Shi     typedef。
371aa3b3690SAlex Shi
372aa3b3690SAlex Shi (c) 当你使用 sparse 按字面的创建一个 **新** 类型来做类型检查的时候。
373aa3b3690SAlex Shi
374aa3b3690SAlex Shi (d) 和标准 C99 类型相同的类型,在某些例外的情况下。
375aa3b3690SAlex Shi
376aa3b3690SAlex Shi     虽然让眼睛和脑筋来适应新的标准类型比如 ``uint32_t`` 不需要花很多时间,可
377aa3b3690SAlex Shi     是有些人仍然拒绝使用它们。
378aa3b3690SAlex Shi
379aa3b3690SAlex Shi     因此,Linux 特有的等同于标准类型的 ``u8/u16/u32/u64`` 类型和它们的有符号
380aa3b3690SAlex Shi     类型是被允许的——尽管在你自己的新代码中,它们不是强制要求要使用的。
381aa3b3690SAlex Shi
382aa3b3690SAlex Shi     当编辑已经使用了某个类型集的已有代码时,你应该遵循那些代码中已经做出的选
383aa3b3690SAlex Shi     择。
384aa3b3690SAlex Shi
385aa3b3690SAlex Shi (e) 可以在用户空间安全使用的类型。
386aa3b3690SAlex Shi
387aa3b3690SAlex Shi     在某些用户空间可见的结构体里,我们不能要求 C99 类型而且不能用上面提到的
388aa3b3690SAlex Shi     ``u32`` 类型。因此,我们在与用户空间共享的所有结构体中使用 __u32 和类似
389aa3b3690SAlex Shi     的类型。
390aa3b3690SAlex Shi
391aa3b3690SAlex Shi可能还有其他的情况,不过基本的规则是 **永远不要** 使用 typedef,除非你可以明
392aa3b3690SAlex Shi确的应用上述某个规则中的一个。
393aa3b3690SAlex Shi
394aa3b3690SAlex Shi总的来说,如果一个指针或者一个结构体里的元素可以合理的被直接访问到,那么它们
395aa3b3690SAlex Shi就不应该是一个 typedef。
396aa3b3690SAlex Shi
397aa3b3690SAlex Shi
398aa3b3690SAlex Shi6) 函数
399*54156734SWu XiangCheng-------
400aa3b3690SAlex Shi
401aa3b3690SAlex Shi函数应该简短而漂亮,并且只完成一件事情。函数应该可以一屏或者两屏显示完 (我们
402aa3b3690SAlex Shi都知道 ISO/ANSI 屏幕大小是 80x24),只做一件事情,而且把它做好。
403aa3b3690SAlex Shi
404aa3b3690SAlex Shi一个函数的最大长度是和该函数的复杂度和缩进级数成反比的。所以,如果你有一个理
405aa3b3690SAlex Shi论上很简单的只有一个很长 (但是简单) 的 case 语句的函数,而且你需要在每个 case
406aa3b3690SAlex Shi里做很多很小的事情,这样的函数尽管很长,但也是可以的。
407aa3b3690SAlex Shi
408aa3b3690SAlex Shi不过,如果你有一个复杂的函数,而且你怀疑一个天分不是很高的高中一年级学生可能
409aa3b3690SAlex Shi甚至搞不清楚这个函数的目的,你应该严格遵守前面提到的长度限制。使用辅助函数,
410aa3b3690SAlex Shi并为之取个具描述性的名字 (如果你觉得它们的性能很重要的话,可以让编译器内联它
411aa3b3690SAlex Shi们,这样的效果往往会比你写一个复杂函数的效果要好。)
412aa3b3690SAlex Shi
413aa3b3690SAlex Shi函数的另外一个衡量标准是本地变量的数量。此数量不应超过 5-10 个,否则你的函数
414aa3b3690SAlex Shi就有问题了。重新考虑一下你的函数,把它分拆成更小的函数。人的大脑一般可以轻松
415aa3b3690SAlex Shi的同时跟踪 7 个不同的事物,如果再增多的话,就会糊涂了。即便你聪颖过人,你也可
416aa3b3690SAlex Shi能会记不清你 2 个星期前做过的事情。
417aa3b3690SAlex Shi
418aa3b3690SAlex Shi在源文件里,使用空行隔开不同的函数。如果该函数需要被导出,它的 **EXPORT** 宏
419aa3b3690SAlex Shi应该紧贴在它的结束大括号之下。比如:
420aa3b3690SAlex Shi
421aa3b3690SAlex Shi.. code-block:: c
422aa3b3690SAlex Shi
423aa3b3690SAlex Shi	int system_is_up(void)
424aa3b3690SAlex Shi	{
425aa3b3690SAlex Shi		return system_state == SYSTEM_RUNNING;
426aa3b3690SAlex Shi	}
427aa3b3690SAlex Shi	EXPORT_SYMBOL(system_is_up);
428aa3b3690SAlex Shi
429*54156734SWu XiangCheng6.1) 函数原型
430*54156734SWu XiangCheng*************
431*54156734SWu XiangCheng
432*54156734SWu XiangCheng在函数原型中包含参数名和它们的数据类型。虽然 C 语言里没有这样的要求,但在
433aa3b3690SAlex ShiLinux 里这是提倡的做法,因为这样可以很简单的给读者提供更多的有价值的信息。
434aa3b3690SAlex Shi
435*54156734SWu XiangCheng不要在函数声明里使用 ``extern`` 关键字,因为这会导致代码行变长,并且不是严格
436*54156734SWu XiangCheng必需的。
437*54156734SWu XiangCheng
438*54156734SWu XiangCheng写函数原型时,请保持 `元素顺序规则 <https://lore.kernel.org/mm-commits/CAHk-=wiOCLRny5aifWNhr621kYrJwhfURsa0vFPeUEm8mF0ufg@mail.gmail.com/>`_ 。
439*54156734SWu XiangCheng例如下列函数声明::
440*54156734SWu XiangCheng
441*54156734SWu XiangCheng __init void * __must_check action(enum magic value, size_t size, u8 count,
442*54156734SWu XiangCheng				   char *fmt, ...) __printf(4, 5) __malloc;
443*54156734SWu XiangCheng
444*54156734SWu XiangCheng推荐的函数原型元素顺序是:
445*54156734SWu XiangCheng
446*54156734SWu XiangCheng- 储存类型(下方的 ``static __always_inline`` ,注意 ``__always_inline``
447*54156734SWu XiangCheng  技术上来讲是个属性但被当做 ``inline`` )
448*54156734SWu XiangCheng- 储存类型属性(上方的 ``__init`` ——即节声明,但也像 ``__cold`` )
449*54156734SWu XiangCheng- 返回类型(上方的 ``void *`` )
450*54156734SWu XiangCheng- 返回类型属性(上方的 ``__must_check`` )
451*54156734SWu XiangCheng- 函数名(上方的 ``action`` )
452*54156734SWu XiangCheng- 函数参数(上方的 ``(enum magic value, size_t size, u8 count, char *fmt, ...)`` ,
453*54156734SWu XiangCheng  注意必须写上参数名)
454*54156734SWu XiangCheng- 函数参数属性(上方的 ``__printf(4, 5)`` )
455*54156734SWu XiangCheng- 函数行为属性(上方的 ``__malloc`` )
456*54156734SWu XiangCheng
457*54156734SWu XiangCheng请注意,对于函数 **定义** (即实际函数体),编译器不允许在函数参数之后添加函
458*54156734SWu XiangCheng数参数属性。在这种情况下,它们应该跟随存储类型属性(例如,与上面的 **声明**
459*54156734SWu XiangCheng示例相比,请注意下面的 ``__printf(4, 5)`` 的位置发生了变化)::
460*54156734SWu XiangCheng
461*54156734SWu XiangCheng static __always_inline __init __printf(4, 5) void * __must_check action(enum magic value,
462*54156734SWu XiangCheng		size_t size, u8 count, char *fmt, ...) __malloc
463*54156734SWu XiangCheng {
464*54156734SWu XiangCheng	...
465*54156734SWu XiangCheng }
466aa3b3690SAlex Shi
467aa3b3690SAlex Shi7) 集中的函数退出途径
468*54156734SWu XiangCheng---------------------
469aa3b3690SAlex Shi
470aa3b3690SAlex Shi虽然被某些人声称已经过时,但是 goto 语句的等价物还是经常被编译器所使用,具体
471aa3b3690SAlex Shi形式是无条件跳转指令。
472aa3b3690SAlex Shi
473aa3b3690SAlex Shi当一个函数从多个位置退出,并且需要做一些类似清理的常见操作时,goto 语句就很方
474aa3b3690SAlex Shi便了。如果并不需要清理操作,那么直接 return 即可。
475aa3b3690SAlex Shi
476aa3b3690SAlex Shi选择一个能够说明 goto 行为或它为何存在的标签名。如果 goto 要释放 ``buffer``,
477aa3b3690SAlex Shi一个不错的名字可以是 ``out_free_buffer:`` 。别去使用像 ``err1:`` 和 ``err2:``
478aa3b3690SAlex Shi这样的GW_BASIC 名称,因为一旦你添加或删除了 (函数的) 退出路径,你就必须对它们
479aa3b3690SAlex Shi重新编号,这样会难以去检验正确性。
480aa3b3690SAlex Shi
481aa3b3690SAlex Shi使用 goto 的理由是:
482aa3b3690SAlex Shi
483aa3b3690SAlex Shi- 无条件语句容易理解和跟踪
484aa3b3690SAlex Shi- 嵌套程度减小
485aa3b3690SAlex Shi- 可以避免由于修改时忘记更新个别的退出点而导致错误
486aa3b3690SAlex Shi- 让编译器省去删除冗余代码的工作 ;)
487aa3b3690SAlex Shi
488aa3b3690SAlex Shi.. code-block:: c
489aa3b3690SAlex Shi
490aa3b3690SAlex Shi	int fun(int a)
491aa3b3690SAlex Shi	{
492aa3b3690SAlex Shi		int result = 0;
493aa3b3690SAlex Shi		char *buffer;
494aa3b3690SAlex Shi
495aa3b3690SAlex Shi		buffer = kmalloc(SIZE, GFP_KERNEL);
496aa3b3690SAlex Shi		if (!buffer)
497aa3b3690SAlex Shi			return -ENOMEM;
498aa3b3690SAlex Shi
499aa3b3690SAlex Shi		if (condition1) {
500aa3b3690SAlex Shi			while (loop1) {
501aa3b3690SAlex Shi				...
502aa3b3690SAlex Shi			}
503aa3b3690SAlex Shi			result = 1;
504aa3b3690SAlex Shi			goto out_free_buffer;
505aa3b3690SAlex Shi		}
506aa3b3690SAlex Shi		...
507aa3b3690SAlex Shi	out_free_buffer:
508aa3b3690SAlex Shi		kfree(buffer);
509aa3b3690SAlex Shi		return result;
510aa3b3690SAlex Shi	}
511aa3b3690SAlex Shi
512*54156734SWu XiangCheng一个需要注意的常见错误是 ``单 err 错误`` ,就像这样:
513aa3b3690SAlex Shi
514aa3b3690SAlex Shi.. code-block:: c
515aa3b3690SAlex Shi
516aa3b3690SAlex Shi	err:
517aa3b3690SAlex Shi		kfree(foo->bar);
518aa3b3690SAlex Shi		kfree(foo);
519aa3b3690SAlex Shi		return ret;
520aa3b3690SAlex Shi
521aa3b3690SAlex Shi这段代码的错误是,在某些退出路径上 ``foo`` 是 NULL。通常情况下,通过把它分离
522aa3b3690SAlex Shi成两个错误标签 ``err_free_bar:`` 和 ``err_free_foo:`` 来修复这个错误:
523aa3b3690SAlex Shi
524aa3b3690SAlex Shi.. code-block:: c
525aa3b3690SAlex Shi
526aa3b3690SAlex Shi	 err_free_bar:
527aa3b3690SAlex Shi		kfree(foo->bar);
528aa3b3690SAlex Shi	 err_free_foo:
529aa3b3690SAlex Shi		kfree(foo);
530aa3b3690SAlex Shi		return ret;
531aa3b3690SAlex Shi
532aa3b3690SAlex Shi理想情况下,你应该模拟错误来测试所有退出路径。
533aa3b3690SAlex Shi
534aa3b3690SAlex Shi
535aa3b3690SAlex Shi8) 注释
536*54156734SWu XiangCheng-------
537aa3b3690SAlex Shi
538aa3b3690SAlex Shi注释是好的,不过有过度注释的危险。永远不要在注释里解释你的代码是如何运作的:
539aa3b3690SAlex Shi更好的做法是让别人一看你的代码就可以明白,解释写的很差的代码是浪费时间。
540aa3b3690SAlex Shi
541*54156734SWu XiangCheng一般来说你用注释告诉别人你的代码做了什么,而不是怎么做的。也请你不要把
542aa3b3690SAlex Shi注释放在一个函数体内部:如果函数复杂到你需要独立的注释其中的一部分,你很可能
543aa3b3690SAlex Shi需要回到第六章看一看。你可以做一些小注释来注明或警告某些很聪明 (或者槽糕) 的
544aa3b3690SAlex Shi做法,但不要加太多。你应该做的,是把注释放在函数的头部,告诉人们它做了什么,
545aa3b3690SAlex Shi也可以加上它做这些事情的原因。
546aa3b3690SAlex Shi
547*54156734SWu XiangCheng当注释内核 API 函数时,请使用 kernel-doc 格式。详见
548*54156734SWu XiangChengDocumentation/translations/zh_CN/doc-guide/index.rstscripts/kernel-doc549aa3b3690SAlex Shi
550aa3b3690SAlex Shi长 (多行) 注释的首选风格是:
551aa3b3690SAlex Shi
552aa3b3690SAlex Shi.. code-block:: c
553aa3b3690SAlex Shi
554aa3b3690SAlex Shi	/*
555aa3b3690SAlex Shi	 * This is the preferred style for multi-line
556aa3b3690SAlex Shi	 * comments in the Linux kernel source code.
557aa3b3690SAlex Shi	 * Please use it consistently.
558aa3b3690SAlex Shi	 *
559aa3b3690SAlex Shi	 * Description:  A column of asterisks on the left side,
560aa3b3690SAlex Shi	 * with beginning and ending almost-blank lines.
561aa3b3690SAlex Shi	 */
562aa3b3690SAlex Shi
563aa3b3690SAlex Shi对于在 net/ 和 drivers/net/ 的文件,首选的长 (多行) 注释风格有些不同。
564aa3b3690SAlex Shi
565aa3b3690SAlex Shi.. code-block:: c
566aa3b3690SAlex Shi
567aa3b3690SAlex Shi	/* The preferred comment style for files in net/ and drivers/net
568aa3b3690SAlex Shi	 * looks like this.
569aa3b3690SAlex Shi	 *
570aa3b3690SAlex Shi	 * It is nearly the same as the generally preferred comment style,
571aa3b3690SAlex Shi	 * but there is no initial almost-blank line.
572aa3b3690SAlex Shi	 */
573aa3b3690SAlex Shi
574aa3b3690SAlex Shi注释数据也是很重要的,不管是基本类型还是衍生类型。为了方便实现这一点,每一行
575aa3b3690SAlex Shi应只声明一个数据 (不要使用逗号来一次声明多个数据)。这样你就有空间来为每个数据
576aa3b3690SAlex Shi写一段小注释来解释它们的用途了。
577aa3b3690SAlex Shi
578aa3b3690SAlex Shi
579aa3b3690SAlex Shi9) 你已经把事情弄糟了
580*54156734SWu XiangCheng---------------------
581aa3b3690SAlex Shi
582*54156734SWu XiangCheng这没什么,我们都是这样。可能你长期使用 Unix 的朋友已经告诉你
583aa3b3690SAlex Shi``GNU emacs`` 能自动帮你格式化 C 源代码,而且你也注意到了,确实是这样,不过它
584aa3b3690SAlex Shi所使用的默认值和我们想要的相去甚远 (实际上,甚至比随机打的还要差——无数个猴子
585*54156734SWu XiangCheng在 GNU emacs 里打字永远不会创造出一个好程序)
586*54156734SWu XiangCheng*(译注:Infinite Monkey Theorem)*
587aa3b3690SAlex Shi
588aa3b3690SAlex Shi所以你要么放弃 GNU emacs,要么改变它让它使用更合理的设定。要采用后一个方案,
589aa3b3690SAlex Shi你可以把下面这段粘贴到你的 .emacs 文件里。
590aa3b3690SAlex Shi
591*54156734SWu XiangCheng.. code-block:: elisp
592aa3b3690SAlex Shi
593aa3b3690SAlex Shi  (defun c-lineup-arglist-tabs-only (ignored)
594aa3b3690SAlex Shi    "Line up argument lists by tabs, not spaces"
595aa3b3690SAlex Shi    (let* ((anchor (c-langelem-pos c-syntactic-element))
596aa3b3690SAlex Shi           (column (c-langelem-2nd-pos c-syntactic-element))
597aa3b3690SAlex Shi           (offset (- (1+ column) anchor))
598aa3b3690SAlex Shi           (steps (floor offset c-basic-offset)))
599aa3b3690SAlex Shi      (* (max steps 1)
600aa3b3690SAlex Shi         c-basic-offset)))
601aa3b3690SAlex Shi
602aa3b3690SAlex Shi  (dir-locals-set-class-variables
603aa3b3690SAlex Shi   'linux-kernel
604aa3b3690SAlex Shi   '((c-mode . (
605aa3b3690SAlex Shi          (c-basic-offset . 8)
606aa3b3690SAlex Shi          (c-label-minimum-indentation . 0)
607aa3b3690SAlex Shi          (c-offsets-alist . (
608aa3b3690SAlex Shi                  (arglist-close         . c-lineup-arglist-tabs-only)
609aa3b3690SAlex Shi                  (arglist-cont-nonempty .
610aa3b3690SAlex Shi                      (c-lineup-gcc-asm-reg c-lineup-arglist-tabs-only))
611aa3b3690SAlex Shi                  (arglist-intro         . +)
612aa3b3690SAlex Shi                  (brace-list-intro      . +)
613aa3b3690SAlex Shi                  (c                     . c-lineup-C-comments)
614aa3b3690SAlex Shi                  (case-label            . 0)
615aa3b3690SAlex Shi                  (comment-intro         . c-lineup-comment)
616aa3b3690SAlex Shi                  (cpp-define-intro      . +)
617aa3b3690SAlex Shi                  (cpp-macro             . -1000)
618aa3b3690SAlex Shi                  (cpp-macro-cont        . +)
619aa3b3690SAlex Shi                  (defun-block-intro     . +)
620aa3b3690SAlex Shi                  (else-clause           . 0)
621aa3b3690SAlex Shi                  (func-decl-cont        . +)
622aa3b3690SAlex Shi                  (inclass               . +)
623aa3b3690SAlex Shi                  (inher-cont            . c-lineup-multi-inher)
624aa3b3690SAlex Shi                  (knr-argdecl-intro     . 0)
625aa3b3690SAlex Shi                  (label                 . -1000)
626aa3b3690SAlex Shi                  (statement             . 0)
627aa3b3690SAlex Shi                  (statement-block-intro . +)
628aa3b3690SAlex Shi                  (statement-case-intro  . +)
629aa3b3690SAlex Shi                  (statement-cont        . +)
630aa3b3690SAlex Shi                  (substatement          . +)
631aa3b3690SAlex Shi                  ))
632aa3b3690SAlex Shi          (indent-tabs-mode . t)
633aa3b3690SAlex Shi          (show-trailing-whitespace . t)
634aa3b3690SAlex Shi          ))))
635aa3b3690SAlex Shi
636aa3b3690SAlex Shi  (dir-locals-set-directory-class
637aa3b3690SAlex Shi   (expand-file-name "~/src/linux-trees")
638aa3b3690SAlex Shi   'linux-kernel)
639aa3b3690SAlex Shi
640aa3b3690SAlex Shi这会让 emacs 在 ``~/src/linux-trees`` 下的 C 源文件获得更好的内核代码风格。
641aa3b3690SAlex Shi
642aa3b3690SAlex Shi不过就算你尝试让 emacs 正确的格式化代码失败了,也并不意味着你失去了一切:还可
643aa3b3690SAlex Shi以用 ``indent`` 。
644aa3b3690SAlex Shi
645aa3b3690SAlex Shi不过,GNU indent 也有和 GNU emacs 一样有问题的设定,所以你需要给它一些命令选
646aa3b3690SAlex Shi项。不过,这还不算太糟糕,因为就算是 GNU indent 的作者也认同 K&R 的权威性
647aa3b3690SAlex Shi(GNU 的人并不是坏人,他们只是在这个问题上被严重的误导了),所以你只要给 indent
648aa3b3690SAlex Shi指定选项 ``-kr -i8`` (代表 ``K&R,8 字符缩进``),或使用 ``scripts/Lindent``
649aa3b3690SAlex Shi这样就可以以最时髦的方式缩进源代码。
650aa3b3690SAlex Shi
651aa3b3690SAlex Shi``indent`` 有很多选项,特别是重新格式化注释的时候,你可能需要看一下它的手册。
652aa3b3690SAlex Shi不过记住: ``indent`` 不能修正坏的编程习惯。
653aa3b3690SAlex Shi
654*54156734SWu XiangCheng请注意,您还可以使用 ``clang-format`` 工具帮助您处理这些规则,快速自动重新格
655*54156734SWu XiangCheng式化部分代码,并审阅整个文件以发现代码风格错误、打字错误和可能的改进。它还可
656*54156734SWu XiangCheng以方便地排序 ``#include`` ,对齐变量/宏,重排文本和其他类似任务。
657*54156734SWu XiangCheng详见 Documentation/process/clang-format.rst658*54156734SWu XiangCheng
659aa3b3690SAlex Shi
660aa3b3690SAlex Shi10) Kconfig 配置文件
661*54156734SWu XiangCheng--------------------
662aa3b3690SAlex Shi
663aa3b3690SAlex Shi对于遍布源码树的所有 Kconfig* 配置文件来说,它们缩进方式有所不同。紧挨着
664aa3b3690SAlex Shi``config`` 定义的行,用一个制表符缩进,然而 help 信息的缩进则额外增加 2 个空
665aa3b3690SAlex Shi格。举个例子::
666aa3b3690SAlex Shi
667aa3b3690SAlex Shi  config AUDIT
668aa3b3690SAlex Shi	bool "Auditing support"
669aa3b3690SAlex Shi	depends on NET
670aa3b3690SAlex Shi	help
671aa3b3690SAlex Shi	  Enable auditing infrastructure that can be used with another
672aa3b3690SAlex Shi	  kernel subsystem, such as SELinux (which requires this for
673aa3b3690SAlex Shi	  logging of avc messages output).  Does not do system-call
674aa3b3690SAlex Shi	  auditing without CONFIG_AUDITSYSCALL.
675aa3b3690SAlex Shi
676aa3b3690SAlex Shi而那些危险的功能 (比如某些文件系统的写支持) 应该在它们的提示字符串里显著的声
677aa3b3690SAlex Shi明这一点::
678aa3b3690SAlex Shi
679aa3b3690SAlex Shi  config ADFS_FS_RW
680aa3b3690SAlex Shi	bool "ADFS write support (DANGEROUS)"
681aa3b3690SAlex Shi	depends on ADFS_FS
682aa3b3690SAlex Shi	...
683aa3b3690SAlex Shi
684cd238effSMauro Carvalho Chehab要查看配置文件的完整文档,请看 Documentation/kbuild/kconfig-language.rst685aa3b3690SAlex Shi
686aa3b3690SAlex Shi
687aa3b3690SAlex Shi11) 数据结构
688*54156734SWu XiangCheng------------
689aa3b3690SAlex Shi
690aa3b3690SAlex Shi如果一个数据结构,在创建和销毁它的单线执行环境之外可见,那么它必须要有一个引
691aa3b3690SAlex Shi用计数器。内核里没有垃圾收集 (并且内核之外的垃圾收集慢且效率低下),这意味着你
692aa3b3690SAlex Shi绝对需要记录你对这种数据结构的使用情况。
693aa3b3690SAlex Shi
694aa3b3690SAlex Shi引用计数意味着你能够避免上锁,并且允许多个用户并行访问这个数据结构——而不需要
695aa3b3690SAlex Shi担心这个数据结构仅仅因为暂时不被使用就消失了,那些用户可能不过是沉睡了一阵或
696aa3b3690SAlex Shi者做了一些其他事情而已。
697aa3b3690SAlex Shi
698aa3b3690SAlex Shi注意上锁 **不能** 取代引用计数。上锁是为了保持数据结构的一致性,而引用计数是一
699aa3b3690SAlex Shi个内存管理技巧。通常二者都需要,不要把两个搞混了。
700aa3b3690SAlex Shi
701aa3b3690SAlex Shi很多数据结构实际上有 2 级引用计数,它们通常有不同 ``类`` 的用户。子类计数器统
702aa3b3690SAlex Shi计子类用户的数量,每当子类计数器减至零时,全局计数器减一。
703aa3b3690SAlex Shi
704aa3b3690SAlex Shi这种 ``多级引用计数`` 的例子可以在内存管理 (``struct mm_struct``: mm_users 和
705aa3b3690SAlex Shimm_count),和文件系统 (``struct super_block``: s_count 和 s_active) 中找到。
706aa3b3690SAlex Shi
707aa3b3690SAlex Shi记住:如果另一个执行线索可以找到你的数据结构,但这个数据结构没有引用计数器,
708aa3b3690SAlex Shi这里几乎肯定是一个 bug。
709aa3b3690SAlex Shi
710aa3b3690SAlex Shi
711aa3b3690SAlex Shi12) 宏,枚举和RTL
712*54156734SWu XiangCheng-----------------
713aa3b3690SAlex Shi
714aa3b3690SAlex Shi用于定义常量的宏的名字及枚举里的标签需要大写。
715aa3b3690SAlex Shi
716aa3b3690SAlex Shi.. code-block:: c
717aa3b3690SAlex Shi
718aa3b3690SAlex Shi	#define CONSTANT 0x12345
719aa3b3690SAlex Shi
720aa3b3690SAlex Shi在定义几个相关的常量时,最好用枚举。
721aa3b3690SAlex Shi
722aa3b3690SAlex Shi宏的名字请用大写字母,不过形如函数的宏的名字可以用小写字母。
723aa3b3690SAlex Shi
724*54156734SWu XiangCheng通常如果能写成内联函数就不要写成像函数的宏。
725aa3b3690SAlex Shi
726aa3b3690SAlex Shi含有多个语句的宏应该被包含在一个 do-while 代码块里:
727aa3b3690SAlex Shi
728aa3b3690SAlex Shi.. code-block:: c
729aa3b3690SAlex Shi
730aa3b3690SAlex Shi	#define macrofun(a, b, c)			\
731aa3b3690SAlex Shi		do {					\
732aa3b3690SAlex Shi			if (a == 5)			\
733aa3b3690SAlex Shi				do_this(b, c);		\
734aa3b3690SAlex Shi		} while (0)
735aa3b3690SAlex Shi
736aa3b3690SAlex Shi使用宏的时候应避免的事情:
737aa3b3690SAlex Shi
738aa3b3690SAlex Shi1) 影响控制流程的宏:
739aa3b3690SAlex Shi
740aa3b3690SAlex Shi.. code-block:: c
741aa3b3690SAlex Shi
742aa3b3690SAlex Shi	#define FOO(x)					\
743aa3b3690SAlex Shi		do {					\
744aa3b3690SAlex Shi			if (blah(x) < 0)		\
745aa3b3690SAlex Shi				return -EBUGGERED;	\
746aa3b3690SAlex Shi		} while (0)
747aa3b3690SAlex Shi
748aa3b3690SAlex Shi**非常** 不好。它看起来像一个函数,不过却能导致 ``调用`` 它的函数退出;不要打
749aa3b3690SAlex Shi乱读者大脑里的语法分析器。
750aa3b3690SAlex Shi
751aa3b3690SAlex Shi2) 依赖于一个固定名字的本地变量的宏:
752aa3b3690SAlex Shi
753aa3b3690SAlex Shi.. code-block:: c
754aa3b3690SAlex Shi
755aa3b3690SAlex Shi	#define FOO(val) bar(index, val)
756aa3b3690SAlex Shi
757aa3b3690SAlex Shi可能看起来像是个不错的东西,不过它非常容易把读代码的人搞糊涂,而且容易导致看起
758aa3b3690SAlex Shi来不相关的改动带来错误。
759aa3b3690SAlex Shi
760aa3b3690SAlex Shi3) 作为左值的带参数的宏: FOO(x) = y;如果有人把 FOO 变成一个内联函数的话,这
761aa3b3690SAlex Shi   种用法就会出错了。
762aa3b3690SAlex Shi
763aa3b3690SAlex Shi4) 忘记了优先级:使用表达式定义常量的宏必须将表达式置于一对小括号之内。带参数
764aa3b3690SAlex Shi   的宏也要注意此类问题。
765aa3b3690SAlex Shi
766aa3b3690SAlex Shi.. code-block:: c
767aa3b3690SAlex Shi
768aa3b3690SAlex Shi	#define CONSTANT 0x4000
769aa3b3690SAlex Shi	#define CONSTEXP (CONSTANT | 3)
770aa3b3690SAlex Shi
771aa3b3690SAlex Shi5) 在宏里定义类似函数的本地变量时命名冲突:
772aa3b3690SAlex Shi
773aa3b3690SAlex Shi.. code-block:: c
774aa3b3690SAlex Shi
775aa3b3690SAlex Shi	#define FOO(x)				\
776aa3b3690SAlex Shi	({					\
777aa3b3690SAlex Shi		typeof(x) ret;			\
778aa3b3690SAlex Shi		ret = calc_ret(x);		\
779aa3b3690SAlex Shi		(ret);				\
780aa3b3690SAlex Shi	})
781aa3b3690SAlex Shi
782*54156734SWu XiangChengret 是本地变量的通用名字—— __foo_ret 更不容易与一个已存在的变量冲突。
783aa3b3690SAlex Shi
784aa3b3690SAlex Shicpp 手册对宏的讲解很详细。gcc internals 手册也详细讲解了 RTL,内核里的汇编语
785aa3b3690SAlex Shi言经常用到它。
786aa3b3690SAlex Shi
787aa3b3690SAlex Shi
788aa3b3690SAlex Shi13) 打印内核消息
789*54156734SWu XiangCheng----------------
790aa3b3690SAlex Shi
791*54156734SWu XiangCheng内核开发者应该看起来有文化。请一定注意内核信息的拼写,以给人良好的印象。
792aa3b3690SAlex Shi不要用不规范的单词比如 ``dont``,而要用 ``do not`` 或者 ``don't`` 。保证这些信
793*54156734SWu XiangCheng息简单明了、无歧义。
794aa3b3690SAlex Shi
795aa3b3690SAlex Shi内核信息不必以英文句号结束。
796aa3b3690SAlex Shi
797aa3b3690SAlex Shi在小括号里打印数字 (%d) 没有任何价值,应该避免这样做。
798aa3b3690SAlex Shi
799aa3b3690SAlex Shi<linux/device.h> 里有一些驱动模型诊断宏,你应该使用它们,以确保信息对应于正确
800aa3b3690SAlex Shi的设备和驱动,并且被标记了正确的消息级别。这些宏有:dev_err(), dev_warn(),
801aa3b3690SAlex Shidev_info() 等等。对于那些不和某个特定设备相关连的信息,<linux/printk.h> 定义
802aa3b3690SAlex Shi了 pr_notice(), pr_info(), pr_warn(), pr_err() 和其他。
803aa3b3690SAlex Shi
804aa3b3690SAlex Shi写出好的调试信息可以是一个很大的挑战;一旦你写出后,这些信息在远程除错时能提
805aa3b3690SAlex Shi供极大的帮助。然而打印调试信息的处理方式同打印非调试信息不同。其他 pr_XXX()
806aa3b3690SAlex Shi函数能无条件地打印,pr_debug() 却不;默认情况下它不会被编译,除非定义了 DEBUG
807aa3b3690SAlex Shi或设定了 CONFIG_DYNAMIC_DEBUG。实际这同样是为了 dev_dbg(),一个相关约定是在一
808aa3b3690SAlex Shi个已经开启了 DEBUG 时,使用 VERBOSE_DEBUG 来添加 dev_vdbg()。
809aa3b3690SAlex Shi
810*54156734SWu XiangCheng许多子系统拥有 Kconfig 调试选项来开启对应 Makefile 里面的 -DDEBUG;在其他
811aa3b3690SAlex Shi情况下,特殊文件使用 #define DEBUG。当一条调试信息需要被无条件打印时,例如,
812aa3b3690SAlex Shi如果已经包含一个调试相关的 #ifdef 条件,printk(KERN_DEBUG ...) 就可被使用。
813aa3b3690SAlex Shi
814aa3b3690SAlex Shi
815aa3b3690SAlex Shi14) 分配内存
816*54156734SWu XiangCheng------------
817aa3b3690SAlex Shi
818aa3b3690SAlex Shi内核提供了下面的一般用途的内存分配函数:
819aa3b3690SAlex Shikmalloc(), kzalloc(), kmalloc_array(), kcalloc(), vmalloc() 和 vzalloc()。
820*54156734SWu XiangCheng请参考 API 文档以获取有关它们的详细信息:
821*54156734SWu XiangChengDocumentation/translations/zh_CN/core-api/memory-allocation.rst822aa3b3690SAlex Shi
823aa3b3690SAlex Shi传递结构体大小的首选形式是这样的:
824aa3b3690SAlex Shi
825aa3b3690SAlex Shi.. code-block:: c
826aa3b3690SAlex Shi
827aa3b3690SAlex Shi	p = kmalloc(sizeof(*p), ...);
828aa3b3690SAlex Shi
829aa3b3690SAlex Shi另外一种传递方式中,sizeof 的操作数是结构体的名字,这样会降低可读性,并且可能
830aa3b3690SAlex Shi会引入 bug。有可能指针变量类型被改变时,而对应的传递给内存分配函数的 sizeof
831aa3b3690SAlex Shi的结果不变。
832aa3b3690SAlex Shi
833aa3b3690SAlex Shi强制转换一个 void 指针返回值是多余的。C 语言本身保证了从 void 指针到其他任何
834aa3b3690SAlex Shi指针类型的转换是没有问题的。
835aa3b3690SAlex Shi
836aa3b3690SAlex Shi分配一个数组的首选形式是这样的:
837aa3b3690SAlex Shi
838aa3b3690SAlex Shi.. code-block:: c
839aa3b3690SAlex Shi
840aa3b3690SAlex Shi	p = kmalloc_array(n, sizeof(...), ...);
841aa3b3690SAlex Shi
842aa3b3690SAlex Shi分配一个零长数组的首选形式是这样的:
843aa3b3690SAlex Shi
844aa3b3690SAlex Shi.. code-block:: c
845aa3b3690SAlex Shi
846aa3b3690SAlex Shi	p = kcalloc(n, sizeof(...), ...);
847aa3b3690SAlex Shi
848*54156734SWu XiangCheng两种形式都会检查分配 n * sizeof(...) 大小时内存的溢出,如果溢出返回 NULL。
849aa3b3690SAlex Shi
850*54156734SWu XiangCheng在没有 __GFP_NOWARN 的情况下使用时,这些通用分配函数都会在失败时发起堆栈转储,
851*54156734SWu XiangCheng因此当返回NULL时,没有必要发出额外的失败消息。
852aa3b3690SAlex Shi
853aa3b3690SAlex Shi15) 内联弊病
854*54156734SWu XiangCheng------------
855aa3b3690SAlex Shi
856aa3b3690SAlex Shi有一个常见的误解是 ``内联`` 是 gcc 提供的可以让代码运行更快的一个选项。虽然使
857aa3b3690SAlex Shi用内联函数有时候是恰当的 (比如作为一种替代宏的方式,请看第十二章),不过很多情
858aa3b3690SAlex Shi况下不是这样。inline 的过度使用会使内核变大,从而使整个系统运行速度变慢。
859aa3b3690SAlex Shi因为体积大内核会占用更多的指令高速缓存,而且会导致 pagecache 的可用内存减少。
860aa3b3690SAlex Shi想象一下,一次 pagecache 未命中就会导致一次磁盘寻址,将耗时 5 毫秒。5 毫秒的
861aa3b3690SAlex Shi时间内 CPU 能执行很多很多指令。
862aa3b3690SAlex Shi
863aa3b3690SAlex Shi一个基本的原则是如果一个函数有 3 行以上,就不要把它变成内联函数。这个原则的一
864aa3b3690SAlex Shi个例外是,如果你知道某个参数是一个编译时常量,而且因为这个常量你确定编译器在
865aa3b3690SAlex Shi编译时能优化掉你的函数的大部分代码,那仍然可以给它加上 inline 关键字。
866aa3b3690SAlex Shikmalloc() 内联函数就是一个很好的例子。
867aa3b3690SAlex Shi
868aa3b3690SAlex Shi人们经常主张给 static 的而且只用了一次的函数加上 inline,如此不会有任何损失,
869aa3b3690SAlex Shi因为没有什么好权衡的。虽然从技术上说这是正确的,但是实际上这种情况下即使不加
870aa3b3690SAlex Shiinline gcc 也可以自动使其内联。而且其他用户可能会要求移除 inline,由此而来的
871aa3b3690SAlex Shi争论会抵消 inline 自身的潜在价值,得不偿失。
872aa3b3690SAlex Shi
873aa3b3690SAlex Shi
874aa3b3690SAlex Shi16) 函数返回值及命名
875*54156734SWu XiangCheng--------------------
876aa3b3690SAlex Shi
877aa3b3690SAlex Shi函数可以返回多种不同类型的值,最常见的一种是表明函数执行成功或者失败的值。这样
878aa3b3690SAlex Shi的一个值可以表示为一个错误代码整数 (-Exxx=失败,0=成功) 或者一个 ``成功``
879aa3b3690SAlex Shi布尔值 (0=失败,非0=成功)。
880aa3b3690SAlex Shi
881aa3b3690SAlex Shi混合使用这两种表达方式是难于发现的 bug 的来源。如果 C 语言本身严格区分整形和
882aa3b3690SAlex Shi布尔型变量,那么编译器就能够帮我们发现这些错误... 不过 C 语言不区分。为了避免
883aa3b3690SAlex Shi产生这种 bug,请遵循下面的惯例::
884aa3b3690SAlex Shi
885aa3b3690SAlex Shi	如果函数的名字是一个动作或者强制性的命令,那么这个函数应该返回错误代
886*54156734SWu XiangCheng	码整数。如果是一个判断,那么函数应该返回一个“成功”布尔值。
887aa3b3690SAlex Shi
888aa3b3690SAlex Shi比如, ``add work`` 是一个命令,所以 add_work() 在成功时返回 0,在失败时返回
889aa3b3690SAlex Shi-EBUSY。类似的,因为 ``PCI device present`` 是一个判断,所以 pci_dev_present()
890aa3b3690SAlex Shi在成功找到一个匹配的设备时应该返回 1,如果找不到时应该返回 0。
891aa3b3690SAlex Shi
892aa3b3690SAlex Shi所有 EXPORTed 函数都必须遵守这个惯例,所有的公共函数也都应该如此。私有
893aa3b3690SAlex Shi(static) 函数不需要如此,但是我们也推荐这样做。
894aa3b3690SAlex Shi
895*54156734SWu XiangCheng返回值是实际计算结果而不是计算是否成功的标志的函数不受此惯例的限制。通常
896aa3b3690SAlex Shi他们通过返回一些正常值范围之外的结果来表示出错。典型的例子是返回指针的函数,
897aa3b3690SAlex Shi他们使用 NULL 或者 ERR_PTR 机制来报告错误。
898aa3b3690SAlex Shi
899*54156734SWu XiangCheng17) 使用布尔类型
900*54156734SWu XiangCheng----------------
901aa3b3690SAlex Shi
902*54156734SWu XiangChengLinux内核布尔(bool)类型是C99 _Bool类型的别名。布尔值只能为0或1,而对布尔的
903*54156734SWu XiangCheng隐式或显式转换将自动将值转换为true或false。在使用布尔类型时 **不需要** 构造,
904*54156734SWu XiangCheng它会消除一类错误。
905*54156734SWu XiangCheng
906*54156734SWu XiangCheng使用布尔值时,应使用true和false定义,而不是1和0。
907*54156734SWu XiangCheng
908*54156734SWu XiangCheng布尔函数返回类型和堆栈变量总是可以在适当的时候使用。鼓励使用布尔来提高可读性,
909*54156734SWu XiangCheng并且布尔值在存储时通常比“int”更好。
910*54156734SWu XiangCheng
911*54156734SWu XiangCheng如果缓存行布局或值的大小很重要,请不要使用布尔,因为其大小和对齐方式根据编译
912*54156734SWu XiangCheng的体系结构而不同。针对对齐和大小进行优化的结构体不应使用布尔。
913*54156734SWu XiangCheng
914*54156734SWu XiangCheng如果一个结构体有多个true/false值,请考虑将它们合并为具有1比特成员的位域,或使
915*54156734SWu XiangCheng用适当的固定宽度类型,如u8。
916*54156734SWu XiangCheng
917*54156734SWu XiangCheng类似地,对于函数参数,多个true/false值可以合并为单个按位的“标志”参数,如果调
918*54156734SWu XiangCheng用点具有裸true/false常量,“标志”参数通常是更具可读性的替代方法。
919*54156734SWu XiangCheng
920*54156734SWu XiangCheng总之,在结构体和参数中有限地使用布尔可以提高可读性。
921*54156734SWu XiangCheng
922*54156734SWu XiangCheng18) 不要重新发明内核宏
923*54156734SWu XiangCheng----------------------
924aa3b3690SAlex Shi
925aa3b3690SAlex Shi头文件 include/linux/kernel.h 包含了一些宏,你应该使用它们,而不要自己写一些
926aa3b3690SAlex Shi它们的变种。比如,如果你需要计算一个数组的长度,使用这个宏
927aa3b3690SAlex Shi
928aa3b3690SAlex Shi.. code-block:: c
929aa3b3690SAlex Shi
930aa3b3690SAlex Shi	#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
931aa3b3690SAlex Shi
932aa3b3690SAlex Shi类似的,如果你要计算某结构体成员的大小,使用
933aa3b3690SAlex Shi
934aa3b3690SAlex Shi.. code-block:: c
935aa3b3690SAlex Shi
936c593642cSPankaj Bharadiya	#define sizeof_field(t, f) (sizeof(((t*)0)->f))
937aa3b3690SAlex Shi
938aa3b3690SAlex Shi还有可以做严格的类型检查的 min() 和 max() 宏,如果你需要可以使用它们。你可以
939aa3b3690SAlex Shi自己看看那个头文件里还定义了什么你可以拿来用的东西,如果有定义的话,你就不应
940aa3b3690SAlex Shi在你的代码里自己重新定义。
941aa3b3690SAlex Shi
942aa3b3690SAlex Shi
943*54156734SWu XiangCheng19) 编辑器模式行和其他需要罗嗦的事情
944*54156734SWu XiangCheng------------------------------------
945aa3b3690SAlex Shi
946aa3b3690SAlex Shi有一些编辑器可以解释嵌入在源文件里的由一些特殊标记标明的配置信息。比如,emacs
947*54156734SWu XiangCheng能够解析被标记成这样的行:
948aa3b3690SAlex Shi
949aa3b3690SAlex Shi.. code-block:: c
950aa3b3690SAlex Shi
951aa3b3690SAlex Shi	-*- mode: c -*-
952aa3b3690SAlex Shi
953aa3b3690SAlex Shi或者这样的:
954aa3b3690SAlex Shi
955aa3b3690SAlex Shi.. code-block:: c
956aa3b3690SAlex Shi
957aa3b3690SAlex Shi	/*
958aa3b3690SAlex Shi	Local Variables:
959aa3b3690SAlex Shi	compile-command: "gcc -DMAGIC_DEBUG_FLAG foo.c"
960aa3b3690SAlex Shi	End:
961aa3b3690SAlex Shi	*/
962aa3b3690SAlex Shi
963*54156734SWu XiangChengVim 能够解析这样的标记:
964aa3b3690SAlex Shi
965aa3b3690SAlex Shi.. code-block:: c
966aa3b3690SAlex Shi
967aa3b3690SAlex Shi	/* vim:set sw=8 noet */
968aa3b3690SAlex Shi
969aa3b3690SAlex Shi不要在源代码中包含任何这样的内容。每个人都有他自己的编辑器配置,你的源文件不
970aa3b3690SAlex Shi应该覆盖别人的配置。这包括有关缩进和模式配置的标记。人们可以使用他们自己定制
971aa3b3690SAlex Shi的模式,或者使用其他可以产生正确的缩进的巧妙方法。
972aa3b3690SAlex Shi
973aa3b3690SAlex Shi
974*54156734SWu XiangCheng20) 内联汇编
975*54156734SWu XiangCheng------------
976aa3b3690SAlex Shi
977aa3b3690SAlex Shi在特定架构的代码中,你可能需要内联汇编与 CPU 和平台相关功能连接。需要这么做时
978aa3b3690SAlex Shi就不要犹豫。然而,当 C 可以完成工作时,不要平白无故地使用内联汇编。在可能的情
979aa3b3690SAlex Shi况下,你可以并且应该用 C 和硬件沟通。
980aa3b3690SAlex Shi
981aa3b3690SAlex Shi请考虑去写捆绑通用位元 (wrap common bits) 的内联汇编的简单辅助函数,别去重复
982aa3b3690SAlex Shi地写下只有细微差异内联汇编。记住内联汇编可以使用 C 参数。
983aa3b3690SAlex Shi
984aa3b3690SAlex Shi大型,有一定复杂度的汇编函数应该放在 .S 文件内,用相应的 C 原型定义在 C 头文
985aa3b3690SAlex Shi件中。汇编函数的 C 原型应该使用 ``asmlinkage`` 。
986aa3b3690SAlex Shi
987aa3b3690SAlex Shi你可能需要把汇编语句标记为 volatile,用来阻止 GCC 在没发现任何副作用后就把它
988aa3b3690SAlex Shi移除了。你不必总是这样做,尽管,这不必要的举动会限制优化。
989aa3b3690SAlex Shi
990aa3b3690SAlex Shi在写一个包含多条指令的单个内联汇编语句时,把每条指令用引号分割而且各占一行,
991*54156734SWu XiangCheng除了最后一条指令外,在每个指令结尾加上 ``\n\t`` ,让汇编输出时可以正确地缩进
992*54156734SWu XiangCheng下一条指令:
993aa3b3690SAlex Shi
994aa3b3690SAlex Shi.. code-block:: c
995aa3b3690SAlex Shi
996aa3b3690SAlex Shi	asm ("magic %reg1, #42\n\t"
997aa3b3690SAlex Shi	     "more_magic %reg2, %reg3"
998aa3b3690SAlex Shi	     : /* outputs */ : /* inputs */ : /* clobbers */);
999aa3b3690SAlex Shi
1000aa3b3690SAlex Shi
1001*54156734SWu XiangCheng21) 条件编译
1002*54156734SWu XiangCheng------------
1003aa3b3690SAlex Shi
1004*54156734SWu XiangCheng只要可能,就不要在 .c 文件里面使用预处理条件 (#if, #ifdef);这样做会让代码更难
1005aa3b3690SAlex Shi阅读并且更难去跟踪逻辑。替代方案是,在头文件中用预处理条件提供给那些 .c 文件
1006aa3b3690SAlex Shi使用,再给 #else 提供一个空桩 (no-op stub) 版本,然后在 .c 文件内无条件地调用
1007aa3b3690SAlex Shi那些 (定义在头文件内的) 函数。这样做,编译器会避免为桩函数 (stub) 的调用生成
1008aa3b3690SAlex Shi任何代码,产生的结果是相同的,但逻辑将更加清晰。
1009aa3b3690SAlex Shi
1010aa3b3690SAlex Shi最好倾向于编译整个函数,而不是函数的一部分或表达式的一部分。与其放一个 ifdef
1011aa3b3690SAlex Shi在表达式内,不如分解出部分或全部表达式,放进一个单独的辅助函数,并应用预处理
1012aa3b3690SAlex Shi条件到这个辅助函数内。
1013aa3b3690SAlex Shi
1014aa3b3690SAlex Shi如果你有一个在特定配置中,可能变成未使用的函数或变量,编译器会警告它定义了但
1015*54156734SWu XiangCheng未使用,请把它标记为 __maybe_unused 而不是将它包含在一个预处理条件中。(然而,
1016*54156734SWu XiangCheng如果一个函数或变量总是未使用,就直接删除它。)
1017aa3b3690SAlex Shi
1018aa3b3690SAlex Shi在代码中,尽可能地使用 IS_ENABLED 宏来转化某个 Kconfig 标记为 C 的布尔
1019aa3b3690SAlex Shi表达式,并在一般的 C 条件中使用它:
1020aa3b3690SAlex Shi
1021aa3b3690SAlex Shi.. code-block:: c
1022aa3b3690SAlex Shi
1023aa3b3690SAlex Shi	if (IS_ENABLED(CONFIG_SOMETHING)) {
1024aa3b3690SAlex Shi		...
1025aa3b3690SAlex Shi	}
1026aa3b3690SAlex Shi
1027aa3b3690SAlex Shi编译器会做常量折叠,然后就像使用 #ifdef 那样去包含或排除代码块,所以这不会带
1028aa3b3690SAlex Shi来任何运行时开销。然而,这种方法依旧允许 C 编译器查看块内的代码,并检查它的正
1029aa3b3690SAlex Shi确性 (语法,类型,符号引用,等等)。因此,如果条件不满足,代码块内的引用符号就
1030aa3b3690SAlex Shi不存在时,你还是必须去用 #ifdef。
1031aa3b3690SAlex Shi
1032aa3b3690SAlex Shi在任何有意义的 #if 或 #ifdef 块的末尾 (超过几行的),在 #endif 同一行的后面写下
1033aa3b3690SAlex Shi注解,注释这个条件表达式。例如:
1034aa3b3690SAlex Shi
1035aa3b3690SAlex Shi.. code-block:: c
1036aa3b3690SAlex Shi
1037aa3b3690SAlex Shi	#ifdef CONFIG_SOMETHING
1038aa3b3690SAlex Shi	...
1039aa3b3690SAlex Shi	#endif /* CONFIG_SOMETHING */
1040aa3b3690SAlex Shi
1041aa3b3690SAlex Shi
1042*54156734SWu XiangCheng附录 I) 参考资料
1043*54156734SWu XiangCheng----------------
1044aa3b3690SAlex Shi
1045*54156734SWu XiangChengThe C Programming Language, 2nd Edition
1046aa3b3690SAlex Shi作者:Brian W. Kernighan 和 Denni M. Ritchie.
1047aa3b3690SAlex ShiPrentice Hall, Inc., 1988.
1048*54156734SWu XiangChengISBN 0-13-110362-8 (平装), 0-13-110370-9 (精装).
1049*54156734SWu XiangCheng
1050*54156734SWu XiangCheng.. note::
1051*54156734SWu XiangCheng
1052*54156734SWu XiangCheng    《C程序设计语言(第2版)》
1053*54156734SWu XiangCheng    作者:[美] Brian W. Kernighan / [美] Dennis M. Ritchie
1054*54156734SWu XiangCheng    译者:徐宝文 / 李志 / 尤晋元(审校)
1055*54156734SWu XiangCheng    出版社:机械工业出版社,2019
1056*54156734SWu XiangCheng    ISBN:9787111617945
1057aa3b3690SAlex Shi
1058aa3b3690SAlex ShiThe Practice of Programming
1059aa3b3690SAlex Shi作者:Brian W. Kernighan 和 Rob Pike.
1060aa3b3690SAlex ShiAddison-Wesley, Inc., 1999.
1061aa3b3690SAlex ShiISBN 0-201-61586-X.
1062aa3b3690SAlex Shi
1063*54156734SWu XiangCheng.. note::
1064*54156734SWu XiangCheng
1065*54156734SWu XiangCheng    《程序设计实践》
1066*54156734SWu XiangCheng    作者:[美] Brian W. Kernighan / [美] Rob Pike
1067*54156734SWu XiangCheng    出版社:机械工业出版社,2005
1068*54156734SWu XiangCheng    ISBN:9787111091578
1069*54156734SWu XiangCheng
1070*54156734SWu XiangCheng    《程序设计实践》
1071*54156734SWu XiangCheng    作者:[美] Brian W. Kernighan / Rob Pike
1072*54156734SWu XiangCheng    译者:裘宗燕
1073*54156734SWu XiangCheng    出版社:机械工业出版社,2000
1074*54156734SWu XiangCheng    ISBN:9787111075738
1075*54156734SWu XiangCheng
1076aa3b3690SAlex ShiGNU 手册 - 遵循 K&R 标准和此文本 - cpp, gcc, gcc internals and indent,
1077cf37fc4aSAlexander A. Klimov都可以从 https://www.gnu.org/manual/ 找到
1078aa3b3690SAlex Shi
1079aa3b3690SAlex ShiWG14 是 C 语言的国际标准化工作组,URL: http://www.open-std.org/JTC1/SC22/WG14/
1080aa3b3690SAlex Shi
1081*54156734SWu XiangCheng内核文档 Documentation/process/coding-style.rst1082*54156734SWu XiangCheng作者 greg@kroah.com 发表于 OLS 2002:
1083aa3b3690SAlex Shihttp://www.kroah.com/linux/talks/ols_2002_kernel_codingstyle_talk/html/
1084