Linux Kernel Coding Style --- Linux内核代码规范

本文详细介绍了Linux内核编程的规范,包括缩进、行长度限制、括号和空格的位置、命名规则、函数设计原则等内容。此外还涉及了数据结构、宏定义、内核消息打印、内存分配等方面的技术细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文主要参考和搬运于:
* Linux kernel coding style
* Linux 内核Coding Style整理

侵删致歉。


1. 缩进

  • 缩进采用8个字符宽度的tab

  • switch和case对齐

switch (suffix) {
case 'G':
case 'g':
    mem <<= 30;
    break;
case 'M':
case 'm':
    mem <<= 20;
    break;
case 'K':
case 'k':
    mem <<= 10;
    /* fall through */
default:
    break;
}

2. 行长度限制

  • 代码行长度要在80个字符以内

3. 括号和空格的位置

括号

  • 下列非函数关键字,左大括号”{“不用换行
    if, switch, for, while, do
if (x is true) {
    we do y
}
  • 函数的左大括号”{“要换行
int function(int x)
{
    body of function
}
  • 以下情况右大括号”}”不单独占一行
do {
    body of do-loop
} while (condition);
if (x == y) {
    ..
} else if (x > y) {
    ...
} else {
    ....
}
  • 单行不需要使用大括号
if (condition)
    action();

if (condition)
    do_this();
else
    do_this();

空格

  • 下列关键字后面使用一个空格
    if, switch, case, for, do, while

  • 定义指针类型时,”*”紧靠变量名或函数名

char *linux_banner;
unsigned long long memparse(char *ptr, char **retptr);
char *match_strdup(substring_t *s);
  • 下列二元和三元操作符左右各留一个空格
    = + - < > * / % | & ^ <= >= == != ? :

  • 下列一元,自加减,结构体成员的操作符不留空格
    & * + - ~ ! sizeof typeof alignof _attribute_ defined
    ++ –
    . ->

  • 不要在行尾留有空格,Git会警告行尾含有空格的patch


4. 命名

  • 全局变量要有描述性的名字
    例如活跃用户统计函数应该命名为count_active_users()而不是cntuser()

  • 局部变量命名要简短
    例如循环计数变量应该命名为i而不是loop_counter


5. Typedefs

除了以下用途外,不要使用typedef:

  • 完全不透明的类型

  • 避免整型数据的困扰

  • 使用kernel的sparse工具做变量类型检查

  • 定义C99标准中的新类型

  • 为了用户空间的类型安全


6. 函数

  • 函数要简短,一个函数只做一件事

  • 函数内部局部变量不要超过5 ~ 10个,否则你需要把函数切割成更小的函数

  • 源码中的函数用一个空行分隔


7. 集中函数的退出

  • 使用goto集中函数的退出
    goto的标签名可以设置为out_free_buffer,避免使用err1:err2:的标签名
int fun(int a)
{
    int result = 0;
    char *buffer;

    buffer = kmalloc(SIZE, GFP_KERNEL);
    if (!buffer)
        return -ENOMEM;

    if (condition1) {
        while (loop1) {
        ...
        }
        result = 1;
        goto out_free_buffer;
    }
    ...
out_free_buffer:
    kfree(buffer);
    return result;
}

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.
 */

11. 数据结构

结构体要包含一个引用计数字段 (内核中没有自动垃圾收集, 需要手动释放内存)

需要保证结构体数据一致性时要加锁

结构体中有时甚至会需要多层的引用计数

ex. struc mm_struct, struct super_block


12. 宏,枚举和RTL

  • 宏定义常量使用大写
#difine CONSTANT 0x123456
  • 宏定义多行语句要放入do - while中
#define macrofun(a, b, c)       \
do {                    \
    if (a == 5)         \
    do_this(b, c);          \
} while (0)
  • 宏定义表达式时要放在()中
#define CONSTANT 0x4000
#define CONSTEXP (CONSTANT | 3)
  • 使用宏定义时要避免下列情况:

1) 影响控制流,如在宏定义中return

#define FOO(x)              \
do {                    \
    if (blah(x) < 0)        \
        return -EBUGGERED;  \
} while (0)

2) 宏定义中含有局部变量

#define FOO(val) bar(index, val)

13. 打印内核消息

  • 消息要简洁清晰明确

  • <linux/device.h\>, <linux/printk.h\>里面有打印消息的宏
    关联设备或驱动<linux/device.h>: dev_err(), dev_warn(), dev_info()等
    不关联设备或驱动<linux/printk.h>: pr_notice() pr_info(), pr_warn(), prerr()等


14. 分配内存

  • 分配内存时使用sizeof(指针), 而不是sizeof(结构体)
p = kmalloc(sizeof(*p), ...);
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值