轉載: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 文件夾中。