转载:http://www.cnblogs.com/wang_yb/p/3532349.htmlhtml
总结linux内核开发的coding style, 便于之后写代码时参考.linux
下面只是罗列一些规则, 具体说明能够参考: 内核源码(Documentation/CodingStyle)vim
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; }
if (condition) do_this; /* bad example */
长度过长的行截断时, 注意保持易读性安全
void fun(int a, int b, int c) { if (condition) printk(KERN_WARNING "Warning this is a long printk with " "3 parameters a: %u b: %u " "c: %u \n", a, b, c); else next_statement; }
int function(int x) { /* 这个大括号 { 另起了一行 */ body of function }
if (x is true) { /* 这个大括号 { 不用另起一行 */ we do y }
if (condition) action();
if (condition) { do_this(); do_that(); } else { otherwise(); }
if, switch, case, for, do, while数据结构
sizeof, typeof, alignof, __attributeapp
s = sizeof(struct file); /* good */ s = sizeof( struct file ); /* bad */
char *linux_banner; unsigned long long memparse(char *ptr, char **retptr); char *match_strdup(substring_t *s);
= + - < > * / % | & ^ <= >= == != ? :编辑器
& * + - ~ ! sizeof typeof alignof __attribute__ defined函数
count_active_users() /* good */ cntusr() /* cnt */
尽可能不要使用 typedef, 使用typedef主要为了下面的用途:工具
1. 彻底不透明的类型(访问这些类型也须要对应的访问函数)oop
ex. pid_t, uid_t, pte_t ... 等等
2. 避免整型数据的困扰
好比int, long类型的长度在不一样体系结构中不一致等等, 使用 u8/u16/u32 来代替整型定义
3. 当使用kernel的sparse工具作变量类型检查时, 能够typedef一个类型.
4. 定义C99标准中的新类型
5. 为了用户空间的类型安全
内核空间的结构体映射到用户空间时使用typedef, 这样即便内核空间的数据结构有变化, 用户空间也能正常运行
int one_func(void) { return 0; } int system_is_up(void) { return system_state == SYSTEM_RUNNING; } EXPORT_SYMBOL(system_is_up);
将函数的退出集中在一块儿, 特别有须要清理内存的时候.(goto 并非洪水猛兽, 有时也颇有用)
int fun(int a) { int result = 0; char *buffer = kmalloc(SIZE); if (buffer == NULL) return -ENOMEM; if (condition1) { while (loop1) { ... } result = 1; goto out; } ... out: kfree(buffer); return result; }
(defun c-lineup-arglist-tabs-only (ignored) "Line up argument lists by tabs, not spaces" (let* ((anchor (c-langelem-pos c-syntactic-element)) (column (c-langelem-2nd-pos c-syntactic-element)) (offset (- (1+ column) anchor)) (steps (floor offset c-basic-offset))) (* (max steps 1) c-basic-offset))) (add-hook 'c-mode-common-hook (lambda () ;; Add kernel style (c-add-style "linux-tabs-only" '("linux" (c-offsets-alist (arglist-cont-nonempty c-lineup-gcc-asm-reg c-lineup-arglist-tabs-only)))))) (add-hook 'c-mode-hook (lambda () (let ((filename (buffer-file-name))) ;; Enable kernel mode for the appropriate files (when (and filename (string-match (expand-file-name "~/src/linux-trees") filename)) (setq indent-tabs-mode t) (c-set-style "linux-tabs-only")))))
config AUDIT bool "Auditing support" depends on NET help Enable auditing infrastructure that can be used with another kernel subsystem, such as SELinux (which requires this for logging of avc messages output). Does not do system-call auditing without CONFIG_AUDITSYSCALL.
config SLUB depends on EXPERIMENTAL && !ARCH_USES_SLAB_PAGE_STRUCT bool "SLUB (Unqueued Allocator)" ...
config ADFS_FS_RW bool "ADFS write support (DANGEROUS)" depends on ADFS_FS ...
Kconfig的说明能够参见: Documentation/kbuild/kconfig-language.txt
ex. struc mm_struct, struct super_block
#define CONSTANT 0x12345
#define macrofun(a, b, c) \ do { \ if (a == 5) \ do_this(b, c); \ } while (0)
#define CONSTANT 0x4000 #define CONSTEXP (CONSTANT | 3)
好比, 不要用 "dont", 而是使用 "do not" 或者 "don't"
p = kmalloc(sizeof(*p), ...);
这样的话, 当p指向其余结构体时, 上面的代码仍然可用
若是一个函数有3行以上, 不要使用 inline 来标记它
好比, add_work() 函数执行成功时返回 0, 失败时返回对应的error-code(ex. -EBUSY)
好比一个返回指针的函数, 经过返回 NULL 来表示失败
内核定义的宏在头文件 include/linux/kernel.h 中, 想定义新的宏时, 首先看看其中是否已有相似的宏可用
不要在代码中加入特定编辑器的内容或者其余工具的配置,
好比 emacs 的配置
-*- mode: c -*- or /* Local Variables: compile-command: "gcc -DMAGIC_DEBUG_FLAG foo.c" End: */
vim 的配置
/* vim:set sw=8 noet */
每一个人使用的开发工具可能都不同, 这样的配置对有些人来讲就是垃圾
这2个工具都在内核代码树中的 scripts 文件夹中。