[問題] static inline的使用時機

看板C_and_CPP (C/C++)作者 (沒有存在感的人)時間9年前 (2016/06/15 03:09), 9年前編輯推噓3(3028)
留言31則, 5人參與, 最新討論串1/2 (看更多)
開發平台(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

06/15 03:13, , 1F
以 C 而言,global func. 加上 static 修飾 , 代表只能在
06/15 03:13, 1F

06/15 03:13, , 2F
該檔案被呼叫, 如 static void func() 放在 a.c , 就不能
06/15 03:13, 2F

06/15 03:14, , 3F
在 b.c 呼叫 func() ; 若不加 static 時,即使 a.h 沒加
06/15 03:14, 3F

06/15 03:15, , 4F
上void func();之宣告, b.c 仍可事先用extern void fun()
06/15 03:15, 4F

06/15 03:15, , 5F
宣告後,調用在 a.c 裡的 func()
06/15 03:15, 5F

06/15 03:16, , 6F
合在一起看,static inline void func(); 代表這個函式只
06/15 03:16, 6F

06/15 03:16, , 7F
能在某個特定檔案裡面被呼叫 , 而且在此檔案裡會建議編譯
06/15 03:16, 7F

06/15 03:17, , 8F
器直接展開 , 並沒衝突。(真正衝突的是extern和static)
06/15 03:17, 8F

06/15 03:17, , 9F
若以 c++ 來講,放在 class 裡面的話又是另一個故事了...
06/15 03:17, 9F
所以說當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

06/15 17:26, , 10F
沒加 static 別人可以自己用 extern 宣告
06/15 17:26, 10F

06/15 17:29, , 11F
inline 的意義是告訴使用者 “定義和宣告合併”
06/15 17:29, 11F

06/15 17:29, , 12F
不管inline有沒有成功都是嗎?
06/15 17:29, 12F

06/15 17:30, , 13F
隱含意義是 “只會有這個實作版本” 因為實作和宣告寫在
06/15 17:30, 13F

06/15 17:30, , 14F
一起了
06/15 17:30, 14F

06/15 17:32, , 15F
至於把程式片段取代函式呼叫 那只是編譯器自己的優化
06/15 17:32, 15F

06/15 17:33, , 16F
inline 沒有成功與否啊 它只是用來提供資訊的關鍵字而已
06/15 17:33, 16F

06/15 17:40, , 17F
對了 GNU 的 inline 效果和 srandard 不一樣
06/15 17:40, 17F

06/15 17:42, , 18F
但是兩者對 inline 的定義卻是相同的
06/15 17:42, 18F

06/15 17:42, , 19F
兩個都拿來看看應該可以找出 inline 的本質
06/15 17:42, 19F
關於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

06/16 14:30, , 20F
C 和 C++ 的 inline 規則不太一樣,可以分開討論
06/16 14:30, 20F

06/16 15:41, , 21F
是喔?有人可以補充一下C++的inline嗎?
06/16 15:41, 21F

06/16 15:42, , 22F
我只知道一個大家都說別用的inline namespace....
06/16 15:42, 22F

06/16 15:46, , 23F
怎麼會?inline namespace很有用阿
06/16 15:46, 23F

06/16 16:32, , 24F
Google C++ Style就建議不要用....
06/16 16:32, 24F

06/16 22:17, , 25F
好吧,那就聽google的吧
06/16 22:17, 25F

06/16 22:18, , 26F
不過我比較想知道原因就是了
06/16 22:18, 26F

06/16 23:13, , 27F
在 C 如果只有使用 inline 而沒有加 static 或 extern
06/16 23:13, 27F

06/16 23:16, , 28F
inline 被接受時就可正常使用,外部不可 extern
06/16 23:16, 28F

06/16 23:20, , 29F
inline 被拒絕時會造成 undefined reference error
06/16 23:20, 29F

06/16 23:23, , 30F
若要避免錯誤發生要在其中一個 .c 用 extern inline 宣告
06/16 23:23, 30F

06/16 23:23, , 31F
這樣那個 .c 的版本就會在 inline 失敗的時候被使用
06/16 23:23, 31F
文章代碼(AID): #1NO5PrlD (C_and_CPP)
文章代碼(AID): #1NO5PrlD (C_and_CPP)