Linux Kernel 代碼藝術——編譯時間斷言

來源:互聯網
上載者:User

本系列文章主要寫我在閱讀Linux核心過程中,關注的比較難以理解但又設計巧妙的程式碼片段(不關注OS的各個模組的設計思想,此部分我準備寫在“深入理解Linux Kernel” 系列文章中),一來通過核心代碼複習一下C語言及組合語言的文法,二來學習核心開發大牛們書寫代碼的風格及思路。

在核心檔案 include/linux/bug.h中,有下面兩行的宏定義:






2 3 4 5 6    e.g. in a structure initializer (or where-ever else comma expressions    aren't permitted). */

以第一個分析,它表示的是:檢查運算式e是否為0,為0編譯通過且返回0;如果不為0,則編譯不通過。

可能從這個宏的名字上看可能容易理解錯,或者改為“BUILD_BUG_OR_ZERO”更好,關於這個的討論有人也提交這個patch(http://lkml.indiana.edu/hypermail/linux/kernel/0703.1/1546.html),但未能被社區接受。我們且不管這個宏定義名字怎樣,來逐步分析一下這個宏是如何來實現的:

  sizeof(struct { int : –!!(e); } ))

1. (e): 運算式e的聲明

2. !!(e): 對e的結果進行兩次求非。即如果e開始是0的話,結果就是0;如果e不為0,則結果為1。

3. –!!(e): 再乘以-1。如果第2步結果為0,則仍為0;否則結果為-1。

4. struct { int : –!!(0); }  -->  struct { int : 0; } : 如果e的結果為0,則我們聲明一個結構體擁有一個int型的資料域,並且規定它所佔的位的個數為0。這沒有任何問題,我們認為一切正常。

5. struct { int : –!!(1); }  -->  struct { int : –1; } : 如果e的結果非0,結構體的int型資料域的位域將變為一個負數,將位域聲明為負數這是一個文法的錯誤。

6. 現在要麼結果為聲明了一個位域為0的結構體,要麼出現位域為負數編譯出錯;如果能正確編譯,然後我們對該結構體進行sizeof操作,得到一個類型為size_t的結果,值為0。

再總結一下,BUILD_BUG_ON_ZERO(e) 表示的就是若運算式e結果為0,則編譯通過,該宏的值也為0;若運算式e的結果不為0,則編譯不通過。

這會讓人聯想到C語言中 assert 宏的用法:

  void assert(int expression);

如果參數expression 計算的結果為0,它先向stderr列印一條出錯資訊,然後通過調用 abort 來終止程式運行;否則斷言成立,繼續執行。

我們討論的宏與assert本質區別在於,我們的宏在編譯時間進行測試,而assert宏是在運行時測試。我們希望能儘早地捕獲到我們編譯時間的錯誤,而不是延遲到運行時。我管這種宏用法叫做“編譯時間斷言”,assert為“運行時斷言”。

理解了上面之後,再來看看第二個BUILD_BUG_ON_NULL(e)宏,與第一個類似,用來在編譯時間斷言e是否為NULL,若是這個宏返回(void *)0 (即NULL,與第一個宏的區別);不為NULL時編譯出錯。

除了上面的兩個編譯時間斷言之外,include/linux/bug.h檔案中還有另幾個大家可以思考表示何意,如:

 BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)]))    BUILD_BUG_ON_NOT_POWER_OF_2(n)            \ ==  || (((n) & ((n) - )) != ))

 

含義可以參考檔案中宏定義的注釋說明。

 

-------------------------------------完--------------------------------

 

參考資料:

http://blog.csdn.net/jiyucn/article/details/862085   C語言中關於結構體位域的詳細說明

http://blog.csdn.net/jiyucn/article/details/862062   C語言中sizeof相關問題

http://www.cplusplus.com/reference/cassert/assert/   assert用法說明

http://stackoverflow.com/questions/9229601/what-is-in-c-code   問題及解答均來源於Stackoverflow

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.