看板 C_and_CPP 關於我們 聯絡資訊
開發平台(Platform): (Ex: VC++, GCC, Linux, ...) Linux + gcc 5.3.1 (-std=gnu11) 問題(Question): 正在寫關於inline的文章。 inline在C99/C11中可以有以下用法: inline:看得到此函式的一律用inline(編譯器許可的話),看不到者不能用該函式 函式無對應的位址可供呼叫 除非該函式另外有同名的非inline版本 extern inline: 看得到此函式的一律用inline(編譯器許可的話),看不到者可用函式呼叫。 有對應的位址 static inline我就不懂了。 反正inline不能外部呼叫,為啥要多一個static? 使用的時機是什麼? 感謝 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 90.41.66.248 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1465931381.A.BCD.html
EdisonX: 以 C 而言,global func. 加上 static 修飾 , 代表只能在 06/15 03:13
EdisonX: 該檔案被呼叫, 如 static void func() 放在 a.c , 就不能 06/15 03:13
EdisonX: 在 b.c 呼叫 func() ; 若不加 static 時,即使 a.h 沒加 06/15 03:14
EdisonX: 上void func();之宣告, b.c 仍可事先用extern void fun() 06/15 03:15
EdisonX: 宣告後,調用在 a.c 裡的 func() 06/15 03:15
EdisonX: 合在一起看,static inline void func(); 代表這個函式只 06/15 03:16
EdisonX: 能在某個特定檔案裡面被呼叫 , 而且在此檔案裡會建議編譯 06/15 03:16
EdisonX: 器直接展開 , 並沒衝突。(真正衝突的是extern和static) 06/15 03:17
EdisonX: 若以 c++ 來講,放在 class 裡面的話又是另一個故事了... 06/15 03:17
所以說當inline沒被compiler接受的時候.... inline -> 變成普通函式 -> 外部可用extern呼叫 static inline -> 變成普通static函式 -> 外部不可用extern extern inline -> 變成普通函式 -> 外部可用extern呼叫 當inline被compiler接受時: inline -> 變成inline -> 外部不可用extern static inline -> 變成inline -> 外部不可用extern extern inline -> 變成inline+普通函式 -> 外部可用extern呼叫 請問我的理解有錯嗎? 其實我覺得以現在的compiler的強度根本可以自己決定要不要inline... 這功能變得有點雞肋.... ※ 編輯: wtchen (90.41.66.248), 06/15/2016 04:20:50
CoNsTaR: 沒加 static 別人可以自己用 extern 宣告 06/15 17:26
CoNsTaR: inline 的意義是告訴使用者 “定義和宣告合併” 06/15 17:29
wtchen: 不管inline有沒有成功都是嗎? 06/15 17:29
CoNsTaR: 隱含意義是 “只會有這個實作版本” 因為實作和宣告寫在 06/15 17:30
CoNsTaR: 一起了 06/15 17:30
CoNsTaR: 至於把程式片段取代函式呼叫 那只是編譯器自己的優化 06/15 17:32
CoNsTaR: inline 沒有成功與否啊 它只是用來提供資訊的關鍵字而已 06/15 17:33
CoNsTaR: 對了 GNU 的 inline 效果和 srandard 不一樣 06/15 17:40
CoNsTaR: 但是兩者對 inline 的定義卻是相同的 06/15 17:42
CoNsTaR: 兩個都拿來看看應該可以找出 inline 的本質 06/15 17:42
關於inline的定義在Standard 是6.7.4,不過他的寫法我不是很理解。 所以大部份我是參考 http://www.greenend.org.uk/rjk/tech/inline.html 這邊有一段是這樣: A function where all the declarations (including the definition) mention inline and never extern. There must be a definition in the same translation unit. The standard refers to this as an inline definition. No stand-alone object code is emitted, so this definition can't be called from another translation unit. 我的理解是,compiler看到inline可以自己決定他要真的inline還是維持普通函式。 inline的話,因為變成用Macro的方式代換函式,自然也沒有必要保留此函式的指標了。 至於gcc,參考https://gcc.gnu.org/onlinedocs/gcc/Inline.html static inline的時候,如果該函式的指標從未被使用, 那該函式的assembly code就不會被產生(除非有 -fkeep-inline-functions) 但是如果是沒有static的inline(inline或extern inline), 該函式的assembly code一律會被產生。 另一個值得一提的是, g++會自動把一些member function改成inline(就算沒加inline), gcc則只有在有最佳化參數才會這麼做。 ※ 編輯: wtchen (86.209.24.41), 06/15/2016 19:10:42
lantw44: C 和 C++ 的 inline 規則不太一樣,可以分開討論 06/16 14:30
wtchen: 是喔?有人可以補充一下C++的inline嗎? 06/16 15:41
wtchen: 我只知道一個大家都說別用的inline namespace.... 06/16 15:42
Caesar08: 怎麼會?inline namespace很有用阿 06/16 15:46
wtchen: Google C++ Style就建議不要用.... 06/16 16:32
Caesar08: 好吧,那就聽google的吧 06/16 22:17
Caesar08: 不過我比較想知道原因就是了 06/16 22:18
lantw44: 在 C 如果只有使用 inline 而沒有加 static 或 extern 06/16 23:13
lantw44: inline 被接受時就可正常使用,外部不可 extern 06/16 23:16
lantw44: inline 被拒絕時會造成 undefined reference error 06/16 23:20
lantw44: 若要避免錯誤發生要在其中一個 .c 用 extern inline 宣告 06/16 23:23
lantw44: 這樣那個 .c 的版本就會在 inline 失敗的時候被使用 06/16 23:23