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