C语言基础:附录:C语言编码规范(如Linux内核风格)

Linux内核C语言编码规范深度解析

一、命名规范体系
/* 内核典型命名示例 */
struct inode_operations {          // 结构体后缀_operations
    int (*create) (struct inode *);  // 函数指针明确类型
};

static void __init setup_arch(char **cmdline_p) {  // 双下划线特殊标记
    unsigned long max_pfn;
}
1. 核心规则
  • 变量/函数:全小写+下划线

    int page_cache_release();  // 正确
    int PageCacheRelease();    // 错误
    
  • 类型定义_t后缀保留给POSIX

    typedef unsigned int pmdval_t;  // 正确
    typedef struct page page_t;     // 错误
    
  • 宏/枚举:全大写+下划线

    #define PAGE_SIZE (4096)       // 正确
    enum irqreturn {              // 枚举值全大写
        IRQ_NONE = 0x0000,
        IRQ_HANDLED = 0x0001,
    };
    
2. 特殊约定
  • 内部函数__前缀

    void __init start_kernel(void);
    
  • 调试函数_debug后缀

    static void mempool_debug_show(...);
    

二、代码布局规范
1. 缩进与空格
// 正确缩进示例(8字符制表符)
static int do_fork(unsigned long clone_flags,
          unsigned long stack_start,
          unsigned long stack_size,
          int __user *parent_tidptr,
          int __user *child_tidptr)
{
    struct task_struct *p;
  
    p = copy_process(clone_flags, stack_start, stack_size,
             child_tidptr, NULL, trace);
}
  • 垂直对齐:相似结构参数对齐

  • 操作符空格

    x = y + z;          // 正确
    for (i=0; i<10; i++); // 错误
    
2. 括号规则
// 函数定义括号换行
void schedule(void) 
{
    // ...
}

// 控制语句括号不换行
if (ret < 0) {
    handle_error();
} else {
    process_data();
}

// 复杂条件换行
if (condition1 && 
    (condition2 || condition3) &&
    !condition4) {
    // ...
}

三、注释规范
1. 文档注释标准
/**
 * find_get_page - 根据偏移查找页面缓存
 * @mapping: 地址空间对象
 * @offset: 页面索引
 *
 * 返回值:找到的页面或NULL
 *
 * 该函数会自旋锁保护查找过程...
 */
struct page *find_get_page(struct address_space *mapping, pgoff_t offset)
{
    // ...
}
2. 代码内注释
  • 行尾禁止注释

    /* 错误示例 */
    tmp = a + b; /* 计算总和 */
    
    /* 正确方式 */
    /* 初始化内存区域 */
    memset(area, 0, sizeof(area));
    
  • TODO标记规范

    /* TODO: 需要优化锁机制 */
    

四、宏与预处理
1. 安全宏编写
// 多语句宏必须使用do-while
#define DPRINTK(fmt, args...)        \
    do {                             \
        if (debug)                   \
            printk(fmt, ##args);     \
    } while (0)

// 带参数的表达式必须括号化
#define MIN(x, y) ((x) < (y) ? (x) : (y))
2. 条件编译规范
#ifdef CONFIG_SMP
static inline void smp_mb__before_atomic(void)
{
    /* ... */
}
#else
#define smp_mb__before_atomic() barrier()
#endif /* CONFIG_SMP */

五、最佳实践
1. 函数设计原则
  • 长度控制:不超过2屏(约80行)

  • 参数限制:最多5个参数

  • 错误处理

    /* 错误处理优先 */
    if (register_device() != 0) {
        cleanup_resources();
        return -EIO;
    }
    
2. 内存管理
// 分配与释放对称
struct page *p = alloc_pages(GFP_KERNEL, order);
if (!p)
    return -ENOMEM;
// ...
__free_pages(p, order);

编码规范对照表

要素Linux内核规范GNU规范Google规范
缩进8字符制表符2空格缩进2空格缩进
函数命名全小写下划线式小写+下划线驼峰式
宏定义全大写_下划线全大写_下划线kConstantNaming
大括号控制语句不换行单独成行同行开始
注释风格C89 /* */C99 // 注释混合使用

规范检查工具链

# 使用checkpatch.pl检查补丁
./scripts/checkpatch.pl --no-tree mypatch.diff

# clang-format配置示例
BasedOnStyle: Linux
IndentWidth: 8
UseTab: Always
BreakBeforeBraces: Linux

典型错误检测

- int* ptr;   // 指针声明位置错误
+ int *ptr;
- if(cond) {  // 缺少空格
+ if (cond) {

规范采用价值

  1. 提升代码可读性(内核超3000万行代码)
  2. 降低协作成本(全球开发者协同)
  3. 避免隐式错误(如运算符优先级问题)
  4. 符合开源社区准入标准

通过严格遵循内核编码规范,可使项目代码具备工业级质量,建议使用自动化工具持续维护规范一致性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赵鑫亿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值