c語言類型説明符有哪些

來源:魅力女性吧 3.24W
c語言類型説明符有哪些

inline int foo(int a, int b) { return a + b } int main(int argc, char *argv[]){return(1,2)

*ANSI C, ISO/IEC C89/C90:標準中沒有inline關鍵字.

*GNU C89/C90:

1、static inline:函數名標識符的作用域為當前編譯單元(translation unit),允許其他編譯單元中有重名定義. 這裏的inline建議編譯器,函數在被調用時可以直接展開函數體,但是否展開取決於編譯器.(譬如,如果優化級別為-O0,則必須按函數地址調用,此時編譯器會忽略inline請求,將函數編譯為普通函數或者,出現了遞歸調用,編譯器也無法內聯這個函數)

2、inline:在當前編譯單元內,和static inline語義相同,都是建議編譯器在當前編譯單元內展開函數體(是否展開取決於編譯器). 但同時編譯器會對該函數生成一份普通函數的代碼,在其他編譯單元內可以調用,與普通的extern函數調用無異.

3、extern inline:相當詭異. 這樣的函數定義只為內聯而提供. 如果強行用普通函數調用方式調用該函數(譬如,優化級別為-O0,或者按函數指針調用),則鏈接器會認為存在另一個同名的普通函數. 如果沒有這個同名普通函數的定義,則鏈接器會報告找不到符號.

*ISO/IEC C99/C11:

1、static inline:和GNU C89/C90中的語義完全相同.

2、inline:很類似GNU C89/C90中的extern inline. 標準文檔中的解釋相當晦澀:允許(但不要求)編譯器在當前編譯單元內展開函數體(原文的描述是“相比正常的函數調用機制,讓內聯函數調用盡可能快”,而文檔下面的腳註中提到,可能的選擇是“內聯替換”,見ISO/IEC 9899:1999或ISO/IEC 9899:2011),是否內聯由編譯器設計者自行決定,同時也允許外部存在同名的普通函數定義. 經測試新版本的Clang和GCC在標準-std=c99和-std=c11下會在可以內聯的情況下(例如優化級別為-O2)採用內聯版本.

3、但標準文檔中同時也規定了,若在函數聲明中加入extern,則相應的內聯函數定義成為所謂的外部定義,行為和GNU C89/C90的inline相同:在當前編譯單元中建議編譯器展開函數體,同時生成一份普通函數的代碼,在其他編譯單元中也可調用.

4、extern inline:標準文檔中未見extern inline的定義.

*GNU C99/C11:採用與ISO/IEC C99/C11相同的語義.

最新版本的Clang和GCC默認均採用GNU C11標準,因此會出現不優化代碼時找不到內聯函數符號的錯誤

熱門標籤