帶你閱讀linux內核源碼:linux內核源代碼編程規範

關注”技術簡說“,帶你由淺入深學習linux內核源碼。linux內核開發100講免費教程,每週二、週四晚上九點準時更新,敬請收看。進我主頁點”視頻“欄目即可觀看。

linux內核代碼是許許多多遵循相同內核開發規範的牛人們的共同的創造的結晶。作為一名linux內核或者驅動開發工程師,很有必要了解這些內核開發規範。好處有以下幾個:

  • 這些約定或者規範對我們閱讀linux內核源碼、瞭解設計思路有很大幫助
  • 我們基於linux內核做開發,也要往內核裡添加代碼,遵守開發規範,有助於別人閱讀和理解我們的代碼。

linux內核代碼規範約定如下:

1.強烈推薦單行的寬度為八十列。

任何一行超過八十列寬度的語句都應該拆分成多個行,除非超過八十列的部分可以提高可讀性且不會隱藏信息。但是,千萬不要把用戶可見的字符串,比如 printk 的信息,拆分成多行,因為這樣會導致使用 grep 的時候找不到這些信息

2.關於大括號

c語言裡的if,do, while, for語句都會使用到大括號,內核代碼傾向於把左括號放在行末,把右括號放在行首,並且大括號和前面的語句,以及if和後面的語句,都保留一個空格,例如:

帶你閱讀linux內核源碼:linux內核源代碼編程規範

以上紅圈標註都代表一個空格。

3.關於空格

這個還是單獨列出來說明一下吧,因為內核代碼裡用到空格的地方太多了。

Linux 內核風格的空格主要用在一些關鍵字上,即在關鍵字之後添一個空格。值得關注的例外是一些長得像函數的關鍵字,比如:sizeof, typeof, alignof, attribute,在 Linux 中,這些關鍵字的使用都會帶上一對括號,比如sizeof(int)。

所以在下面這些關鍵字後面需要添加一個空格:

<code>

if

,

switch

,

case

,

for

,

do

,

while

/<code>

但是, sizeof, typeof, alignof, attribute 之後則不需要添加空格:

<code>

s

= sizeof(struct file)/<code>

在聲明指針或者返回值為指針的函數時,星號的位置應該緊靠著變量名或函數名,而不是類型名,例如:

<code>

char

*linux_banner;

unsigned

long

long

memparse

(

char

*ptr,

char

**retptr)

;

char

*

match_strdup

(

substring_t

*s)

;/<code>

在二元操作符和三元操作符周圍添加一個空格,例如:

<code>=  +  -  

< >

* / % | & ^

<

=

>

= == != ? :

/<code>

但是不要在一元操作符之後添加空格:

<code>&  *  +  -  ~  !  

sizeof

typeof

alignof

__attribute__ defined/<code>

4.變量命名

C 是一種簡潔粗曠的語言,因此,你的命名也應該是簡潔的。linux內核裡的變量定義應該儘可能簡單,在不產生歧義的情況下,越簡單越好。可以用下劃線,但是絕對不推薦使用大寫字母。所以,內核裡的變量和函數定義不要使用駝峰命名法。

帶你閱讀linux內核源碼:linux內核源代碼編程規範

5.函數

函數應該短小精悍,一個函數只幹一件事。幾百行代碼組成一個函數是不被推薦的。

關鍵函數的前面最好留有註釋。這樣其他人可以快速看懂你的代碼意圖:

帶你閱讀linux內核源碼:linux內核源代碼編程規範

6.註釋

多行註釋推薦格式如下:

<code>/<code>

7.推薦使用函數自注釋

所謂函數自注釋,就是從你的函數名就可以猜到你要幹什麼,比如內核的:

wait_event(), wait_event_interruptible(),
wait_event_interruptible_timeout()等。

帶你閱讀linux內核源碼:linux內核源代碼編程規範

注意,寫代碼不只是寫給現在的自己,也是寫給以後的自己,也是寫給其他人看的。如果你回看你一年前寫的代碼都很陌生,那說明你的代碼規範是有問題的。

8.常量宏和枚舉的命名都是大寫的:

帶你閱讀linux內核源碼:linux內核源代碼編程規範

9.打印內核或者驅動信息

編寫好的調試信息是一項巨大的挑戰,一旦你完成了,這些信息會對遠程調試產生巨大幫助

很多子系統在對應的 makefile 裡都有 Kconfig 調試選項來打開 -DDEBUG,或者是在文件裡定義宏 #define DEBUG。當調試信息可以被無條件打印,或者說已經編譯了和調試有關的 #ifdef 段,那麼 printk(KERN_DEBUG ...) 就可以用來打印調試信息。

10.內聯函數(inline)

Inline關鍵字會讓編譯器將指定的函數體插入並取代每一處調用該函數的地方(上下文),從而節省了每次調用函數帶來的額外時間開支。然而,inline 關鍵字的泛濫,會使內核變大,從而使整個系統運行速度變慢,因為大內核會佔用更多的CPU高速緩存,同時會導致可用內存頁緩存減少。想象一下,一次頁緩存未命中就會導致一次磁盤尋址,這至少耗費5毫秒。5毫秒足夠CPU運行很多很多的指令。

好了,以上就是我們在閱讀linux內核源碼的時候的一些代碼規範的約定。linux源碼作為世界上最規範、最嚴謹的代碼,確實有很多值得我們學習的地方。有時候欣賞內核代碼的時候總有一種賞心悅目的感覺,這可能跟它們的良好的代碼規範有關係吧。

關注”技術簡說“,帶你由淺入深學習linux內核源碼。linux內核開發100講免費教程,每週二、週四晚上九點準時更新,敬請收看。進我主頁點”視頻“欄目即可觀看。


分享到:


相關文章: