推 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