Re: [問題] 全域變數宣告方式

作者: purpose (秀才遇到肥宅兵)   2014-08-28 01:03:15
: 另外偷渡一個問題 最近看到一個.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。
作者: azureblaze (AzureBlaze)   2014-08-28 01:22:00
再不然就根本不要管inline 反正編譯器大概會無視他
作者: PoorLoser (廢文製造機)   2014-08-28 01:24:00
只有在學校練習時用過 inline
作者: gg1122 (99通未接來電)   2014-08-28 08:01:00
原來還有這招 不過我自己連inline都沒宣告過== 謝謝分享!
作者: Killercat (殺人貓™)   2014-08-28 09:10:00
inline裡面邏輯不要太複雜,連static local都出現的話通常也代表這個inline一點都不該inline了
作者: EdisonX (卡卡獸)   2014-08-28 20:07:00
突然想起 M$ 的部份 inline 似乎還會拆檔寫...

Links booklink

Contact Us: admin [ a t ] ucptt.com