Re: [问题] static inline的使用时机

楼主: EdisonX (卡卡兽)   2016-06-16 00:58:16
原文后面提到的东西愈来愈多,此篇一点一点慢慢讨论,
没 k 过 spec., 没追过 assembly code,有误请不吝指正。
先谈 inline 的特性 , 再讨论 static , 用大量的程式码做辅助说明应该会清楚些。
另由于我手边的 vs2010 要用 inline 就得用 cpp ,故暂时先以 c++ 的方式探讨。
以下说的 "DEBUG MODE" 指的是没有任何优化参数;
"RELEASE MODE" 指的是有下 -O2 优化参数。
壹、inline
的确一般的 inline function,实作和宣告会放在同一个档案里面,如下。
例 1.1 (correct)
// mymath.h
#pragma once
inline int inc(int a) { return a+1; }
// main.cpp
#include "mymath.h"
int main() { inc(1) ; return 0;}
若拆成 mymath.h / mymath.cpp 做的话,的确在 compile 时就会有语法上的错误
例 1.2 (error)
// mymath.h
#pragma once
inline int inc(int v);
// mymath.cpp
#include "mymath.h"
inline int inc(int v) { return v+1;}
// main.cpp
#include "mymath.h"
int main() { inc(1) ; return 0;}
inline 做的事情是 "建议" compiler 不要实际产生一个 function,
而是如你说的,像是用 macro 的方式在呼叫的地方做替换,但这件事是叫
"建议",而不是 "绝对"。而这个 "建议",通常在 Debug Mode 都是无效的,
这点不论 gcc 或 vs 都一样。故在 MFC 的一些 src code 会透过 macro 进行
inline switch 作法,也就是在 Debug Mode 时,该函式不实作为 inline 函式;
在 Release Mode 时会实作为 inline 函式,所以 MFC src 会看到另一种副档
名的 src code : XXXX.inl,让人感觉很绕路,但会这么做的原因是想让
编译速度加快,不过我没测过时间就是。
上篇提到的的,compiler 强度可以决定要不要 inline,答案是没错的,
甚至我认为说不定未来 inline 关键字和 register 关键字走向一样的结果,
在 Debug Mode 的时候基本上是完全不理会,一律用一般 function / variable
方式处理;在 Release Mode 也是忽视这二个识别字,因 user 要不要用
inline 或是 register 的建议,对 compiler 而言可能都很烂,还不如让
compiler 自己做就好。这也是为什么 vs release mode 下中断点,有些变量
看不到、有些函式进不去的原因 (因都被优化掉了)。
貮、static
回到 mymath 问题,但若今天的情况是,我在实作 mymath 的所有对外
functions (像是 mysin, mycos, mytan... 等让其他 coder 使用的),
并不打算让其他 coder 在引入 mymath.h 时可以用到 inc 时,我的
inc 就不想放在 mymath.h 里面,只想实作在 mymath.cpp 里,且考虑
到 inc 较适合用 inline,情况就变如下
例 2.1
// mymath.h
#pragma once
double mysin(double x);
double mycos(double x);
// mymath.cpp
#include "mymath.h"
inline int inc(int v) { return v+1;}
double mysin(double x){...}
double mycos(double x){...}
一般 "正常使用" , 没有人在 main.cpp 做 extern 时, Release Mode 下
inc 会被做 inline 没错,但若今天有人无聊,想在 main.cpp 中,hack
到 mymath.cpp 里面的 inc 时,情况就不一样了。
例 2.2
// main.cpp
#include "mymath.h"
extern int inc(int v);
int main() { inc(1) ; return 0;}
这时由于 inc function 在其他档案 extern 出来,在 mymath.cpp 里的 inc
就不会被用 inline 内崁在程式码里,但 extern inline 这特性说真的,主要
还是看 compiler 有没有能力再做 inline。为了避免我原本不想开放、要 inline 的
东西被乱搞,搞成不能变 inline,就在 mymath.cpp 里的 inc
变成 static inline 修饰,让其他人没办法用 extern 抽出来。如下。
例 2.3
// mymath.h
#pragma once
double mysin(double x);
double mycos(double x);
// mymath.cpp
#include "mymath.h"
static inline int inc(int v) { return v+1;}
double mysin(double x){...}
double mycos(double x){...}
// main.cpp
#include "mymath.h"
extern int inc(int v);
int main() { inc(1) ; return 0;} // 这里会报 error, 不让人乱搞
~~~~~~
以上,故事有点长,若叙述有误,请不吝指正。
谢谢收听。
作者: wtchen (没有存在感的人)   2016-06-16 01:52:00
感谢。不知VS对于static inline的function是否会省去产生assembly code的步骤?(compiler允许inline时)
楼主: EdisonX (卡卡兽)   2016-06-16 01:58:00
会省,本质上 inline 是展开 , static 就是 scope 。
作者: suhorng ( )   2016-06-18 13:34:00
记得 static inline 不是都可以直接放 .h 档里XD看得到定义才能 inline, 想要大家 #include 又不能multiple definition 就放 static 吗?
作者: lantw44 (#######################)   2016-06-19 01:28:00
在 C 放 .h 的应该通常都是 static inline?只有写 inline 的话,如果编译器不打算 inline,应该会变成 undefined reference 吧。
楼主: EdisonX (卡卡兽)   2016-06-19 02:09:00
@lantw44 , 我手边的 vs .c 连 inline 都不支援了。
作者: wtchen (没有存在感的人)   2016-06-19 02:17:00
VS的.c有鸟到连inline都不支援喔?
楼主: EdisonX (卡卡兽)   2016-06-19 06:31:00
vs2010 , 可试试。不过话说 vs 对纯 c 的支援一向不好,对新标准的进度也慢
作者: lantw44 (#######################)   2016-06-19 11:18:00
听说 VS 一直都不太在意 C 标准
作者: uranusjr (←這人是超級笨蛋)   2016-06-20 02:21:00
微软只关心 C++ 啊, C 编译器基本上只是顺便做做
作者: wtchen (没有存在感的人)   2016-06-20 15:55:00
不过VS主要就是开发application的,写Windows OS应该不会用VS吧?不像gcc就是做来开发kernel的(好奇MS用啥开发Win OS...)
作者: suhorng ( )   2016-06-22 01:38:00
咦~ 为什么 Visual C 不能拿来开发 OS
作者: wtchen (没有存在感的人)   2016-06-22 15:57:00
我只是猜啦没有这样说,不知道有没有人知道MS怎么开发OS
作者: Caesar08 (Caesar)   2016-06-22 20:39:00
在VC上,C++进展很快,已经支援部分C++17了。不过C就...
作者: wtchen (没有存在感的人)   2016-06-23 02:06:00
MS是用C还是C++写OS阿?
作者: Schottky (顺风相送)   2016-06-23 16:57:00
https://technet.microsoft.com/library/cc767881.aspx照这网页的说法,大部份是用 C 和 C++ 写的,少部份组语而且虽然很少用到,VS 有包含 kernel remote debugger

Links booklink

Contact Us: admin [ a t ] ucptt.com