Catalog
  1. 1. 缩进
  2. 2. 长行字符串进行截断
  3. 3. 大括号和空格
    1. 3.1. 大括号
    2. 3.2. 空格
  4. 4. 命名
    1. 4.1. 全局变量应该有描述性的名称
    2. 4.2. 局部变量尽量一针见血
  5. 5. Typedefs
  6. 6. 函数
  7. 7. 注释
  8. 8.
Linux Kernel Coding Style

入门C语言的时候是通过K&R的《C Language Programming》,发现里面的代码风格是Linux内核一致,因为看着也比较习惯,今天系统的整理一下。

文章参考于https://www.kernel.org/doc/html/latest/process/coding-style.html

缩进

Tabs 用8个字符,因此缩进也是8个字符
case和switch对其,不用缩进

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
switch (suffix) {
case 'G':
case 'g':
mem <<= 30;
break;
case 'M':
case 'm':
mem <<= 20;
break;
case 'K':
case 'k':
mem <<= 10;
fallthrough;
default:
break;
}

不要把多个表达式放在一行

1
2
if (condition) do_this;  //Bad Example
do_something_everytime;

长行字符串进行截断

  1. 超过80列的语句如果不能提高易读性且不会隐藏信息,最好合理的分块
  2. 子串最好比父串短,且都位于父串的右侧以保持易读性

大括号和空格

大括号

  1. 非函数的大括号不换行(如:if,switch,for,while,do等等)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    //Example
    if (x is true) {
    we do y
    }

    switch (action) {
    case KOBJ_ADD:
    return "add";
    case KOBJ_REMOVE:
    return "remove";
    case KOBJ_CHANGE:
    return "change";
    default:
    return NULL;
    }
  2. 函数的大括号换行

    1
    2
    3
    4
    int function(int x)
    {
    body of function
    }
  3. 右大括号在通常情况下是单独成行,但是他后面跟着相同的语句时是一种例外。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    do {
    body of do-loop
    } while (condition);

    if (x == y) {
    ..
    } else if (x > y) {
    ...
    } else {
    ....
    }
  4. 单独的语句不需要大括号

    1
    2
    3
    4
    5
    6
    7
    if (condition)
    action();

    if (condition)
    do_this();
    else
    do_that();
  5. 当if语句有大括号,后面的else即使是一行也要有大括号

    1
    2
    3
    4
    5
    6
    if (condition) {
    do_this();
    do_that();
    } else {
    otherwise();
    }
  6. 在循环中有多条语句的时候需要用大括号

    1
    2
    3
    4
    while (condition) {
    if (test)
    do_something();
    }

空格

  1. 下列 keywords 后面追加一个空格

if, switch, case, for, do, while

  1. sizeof, typeof, alignof 等等之类的后面不需要空格
1
2
3
4
//sizeof后面的小括号也不要加空格
s = sizeof(struct file); //Good Example

s = sizeof( struct file); //Bad Example
  1. 定义指针时, * 紧靠函数名或者变量名
1
2
3
char *linux_banner;
unsigned long long memparse(char *ptr, char **retptr);
char *match_strdup(substring_t *s);
  1. 后缀操作符(++ –)前面不要留空格

  2. 前缀操作符(++ –)后面不要留空格

  3. 结构体成员操作符(. ->)前后都不要留空格

  4. 每行代码之后不要有多余的空格

命名

C is a Spartan language, and so should your naming be. Unlike Modula-2 and Pascal programmers, C programmers do not use cute names like ThisVariableIsATemporaryCounter. A C programmer would call that variable tmp, which is much easier to write, and not the least more difficult to understand.

全局变量应该有描述性的名称

1
2
3
int count_active_users();  //Good Example

int cntusr(); //Bad Example

局部变量尽量一针见血

  1. 如果有临时出现的循环计数,用i比用loop_counter更好
  2. tmp可以作为储存所有类型的临时变量

Typedefs

使用typedef主要为了以下用途:

  1. 完全不透明的类型(只能通过函数访问的类型)

  2. 避免整型数据的困扰
    比如int, long类型的长度在不同体系结构中不一致等等, 使用 u8/u16/u32 来代替整型定义

  3. 当使用kernel的sparse工具做变量类型检查时, 可以typedef一个类型.

  4. 定义C99标准中的新类型

  5. 为了用户空间的类型安全

    内核空间的结构体映射到用户空间时使用typedef, 这样即使内核空间的数据结构有变化, 用户空间也能正常运行

函数

  1. 函数要简洁,一个函数只做一件事情

  2. 函数和函数之间空一行,避免拥挤

注释

  1. 注释代码做了啥,不是如何做的

  2. 多行注释像这样

    1
    2
    3
    4
    5
    6
    7
    8
    /*
    * 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.
    */

  1. 宏定义常量后者标签时使用大写字母

    1
    #define CONSTANT 0x12345
  2. 宏定义多行语句时要放入 do - while 中, 此时宏的名称用小写

    1
    2
    3
    4
    5
    #define macrofun(a, b, c)             
    do {
    if (a == 5)
    do_this(b, c);
    } while (0)
  3. 宏定义表达式时要放在 () 中

1
2
#define CONSTANT 0x4000
#define CONSTEXP (CONSTANT | 3)
Author: Jsthcit
Link: http://jsthcitpizifly.com/2019/10/19/Linux-Kernel-Coding-Style/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Donate
  • 微信
  • 支付寶

Comment