為什麼這篇c全域變數宣告鄉民發文收入到精華區:因為在c全域變數宣告這個討論話題中,有許多相關的文章在討論,這篇最有參考價值!作者purpose (purpose)看板C_and_CPP標題Re: [問題] 全域變數宣告方式時...
: 另外偷渡一個問題 最近看到一個.h
: 有一個函數 static inline void function();
: static 不是local scope 又宣告在.h 讓人call 這有什麼好處嗎??
如同 C++ Primer 所說:「inline 函式應該定義於表頭檔內」,所以不再多講。
比較值得注意的是,為什麼 static inline?
我們知道一個事實「inline 只是對編譯器的請求,可能被忽略」,
當 inline 被拒絕行內擴展時,他的性質就跟 non-inline 函數一樣。
又 C++ 的世界裡,有個「One Definition Rule」,
使得函數通常都不能被重複定義,否則會違反 ODR,
因此 inline 函數,理論上,也需要考慮重複定義的問題。
最初的 inline 函數,其 default linkage 其實是 static。
也就是說以前 inline void function() 跟 static inline void function() 等價。
現代的 C++ 才將 inline 函數 default linkage 改成 external。
那麼猜測原問題中,寫 static inline 應該是衝著 static linkage 而來。
#########################################################
static inline 相較於 extern inline 來說,有以下優缺點。
優點:
(1) 當某個 static inline 函數,於多個 *.cpp 檔有不同實作時,
依然不違反 ODR。
※ 附註:相同狀況換成 extern inline 就會違反 ODR,
根據 C++ 標準,這是未定義行為,實際在 VC++ 的作法是
pick any。也就是可能挑 1.cpp 裡面的實作當代表,也可能
挑選 2.cpp 的實作來當這個 inline 函數的代表,整個程式
中所有用到該 inline 的地方,都會使用該代表的版本。
(2) 當某個 satic inline 函數有不同的實作時,
不論有沒有被 compiler 行內擴展,
程式計算的結果都不會改變,是固定可預期的。
缺點:
當 static inline 函數內部,出現 local static variable 時,
程式計算的結果是難以預期的。
用以下案例來重現此問題:
=========================================================
// 檔案 1.cpp
#include <stdio.h>
void call_2();
static inline int foo() {
static int counter = 0;
return ++counter;
}
int main() {
printf("counter = %d\n", foo());
printf("counter = %d\n", foo());
call_2();
return 0;
}
==========================================================
// 檔案 2.cpp
#include <stdio.h>
static inline int foo() {
static int counter = 0;
return ++counter;
}
void call_2() {
printf("in 2, counter = %d\n", foo());
}
===========================================================
則上述程式的執行結果為:
===========================================================
counter = 1
counter = 2
in 2, counter = 1
===========================================================
除非使用 extern inline,才能得到「in 2, counter = 3」這個預期的結果。
總結來說,只要保持 inline 函數的實作一致,永遠不出現衝突的版本,就不需要
依賴 static inline 的優點 (1) (2)。
也最好永遠不要在 inline 函數內,使用 static variable。
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 124.8.129.83
※ 文章網址: http://www.ptt.cc/bbs/C_and_CPP/M.1409158998.A.E28.html
※ 編輯: purpose (124.8.129.83), 08/28/2014 01:05:40
※ 編輯: purpose (124.8.129.83), 08/28/2014 01:07:49