GNU C語法擴充套件(9)

要研究LINUX核心,C語言是基礎中的基礎,但是LINUX並不是完全的標準C,而是對標準C做了很多擴充套件,這些擴充套件特性對於我們分析核心有著很重要的作用,下面做些總結性的工作。
9、特殊屬性宣告
GNU C允許宣告函式、變數和型別的特殊屬性,以便進行手工的程式碼優化和定製程式碼檢查的方法。
- no return 屬性用於函式,表示該函式從不返回。這可以讓編譯器生成稍微優化的程式碼,最重要的是可以消除不必要的警告資訊比如未初使化的變數。例如:
//include/linux/kernel.h #define ATTRIB_NORET __attribute__((noreturn))... asmlinkage NORET_TYPE void do_exit(long error_code) ATTRIB_NORET;
-
format(ARCHETYPE,STRING-INDEX,FIRST-TO-CHECK)屬性用於函式,表示該函式使用
printf,scanf或strftime風格的引數,使用這類函式最容易犯的錯誤是格式串與引數不匹配,指定format屬性可以讓編譯器根據格式串檢查引數型別。例如:
//include/linux/kernel.h asm linkage int printk(const char* fmt, ...)__attribute__((format(printf,1,2)));
表示第一個引數是格式串,從第二個引數起根據格式串檢查引數。
-
unused屬性用於函式和變數,表示該函式或變數可能不使用,這個屬性可以避免編譯器產生警告資訊。
-
section("section-name")屬性用於函式和變數,通常編譯器將函式放在.text區,變數放在.data區或.bss區,使用section屬性,可以讓編譯器將函式或變數放在指定的節中。例如:
//include/linux/init.h #define __init __attribute__((__section__(".text.init"))) #define __exit __attribute__((unused,__section__(".text.exit"))) #define __init data__attribute__((__section__(".data.init"))) #define __exit data__attribute__((unused,__section__(".data.exit"))) #define __initsetup __attribute__((unused,__section__(".setup.init"))) #define __init_call __attribute__((unused,__section__(".initcall.init"))) #define __exit_call __attribute__((unused,__section__(".exitcall.exit")))
聯結器可以把相同節的程式碼或資料安排在一起,Linux核心很喜歡使用這種技術,例如系統的初始
化程式碼被安排在單獨的一個節,在初始化結束後就可以釋放這部分記憶體。
- aligned(ALIGNMENT) 屬性用於變數、結構或聯合型別,指定變數、結構域、結構或聯合的對齊量,以位元組為單位,例如:
//include/asm-i386/processor.h struct i387_fxsave_struct{ unsigned short cwd; ... }__attribute__((aligned(16)));
表示該結構型別的變數以16位元組對齊。通常編譯器會選擇合適的對齊量,顯示指定對齊通常是由於體系限制、優化等原因。
- packed 屬性用於變數和型別,用於變數或結構域時表示使用最小可能的對齊,用於列舉、結構或聯合型別時表示該型別使用最小的記憶體。例如:
//include/asm-i386/desc.h struct Xgt_desc_struct{ unsigned short size; unsigned long address__attribute__((packed)); };
域address將緊接著size分配。屬性packed的用途大多是定義硬體相關的結構,使元素之間沒有因
對齊而造成的空洞。

圖片發自簡書App