inline 我倒不是很清楚,不过很多关键字不只一种,是为了移植考虑的。
windows 下的很多软件可能没有这么大的负担,他们一般不会考虑着自己写的东西能在别的系统上跑。但开源软件,或者有移植性要求的软件,在开发时要考虑很多问题。
比如我写一个程序,要想在 gcc 和 vc 甚至 tc 上编译都能如期通过,甚至还希望能产生一些好的效果,就要下很多功夫。不同的编译器对标准的支持是不一样的,同样的语句,一旦牵上什么复杂的語法,或实现方式,就不能保证所有的编译器都能对它支持的这么好。
我比如举个例子,当然这个例子只是说明性的,其实不恰当。
假如 vc 不支持内联函数,而 gcc 支持。那么如果有如下代码:
#ifdef (__GNUC__)
#define inline __inline
#elif defined(_MSC_VER)
#define inline
// 由于假设它没有内联机制,所以在预处理时只是单纯的把这个删掉。
inline int negative(int a)
{
return -a;
}
这样在 gcc 里编译,它就会变成一个内联函数。而有 vc 里就会是一个普通函数。这样可以充分发挥一些编译的能力,而读代码的人也不会搞糊涂。
为了让 inline 能看上去最終像我写的那样(也就是标准规定的样子),其它预处理的工作,都要编译想办法解决。
编译器为了在内部能预处理,就要用一些辅助手段,比如增加一些关键字。一般的共识就是,双下划线开头的是内部识别用的,通用程序不能用(学 C 的人一上来就应该被告知过不能用下划线开头取变量名吧~)。这样在编译器内部就有很大的变换余地。你随便开几个头文件看看,凡是有 #ifdef 之类的东西,可能就为了增加一定的可移植性用的。还有可能也是为了向下兼容,比如 vc9.0 来编译 vc6.0 写的东西,不能通过肯定会另人沮丧吧?如果编译能偷偷的预处理,就能把 9.0 新扩展的东西编译进去,而源码不用动。
C 语言的移植性,除了标准库以外是受限制的。所以除了 c89, c99 以外还有很多标准。比如 POSIX 标准(包括 posix.1-1990, posix.2, posix.4, posix.1-1996 什么的),还有 SUS 标准 (SUSv1, SUSv2, SUSv3, SUSv4)什么的。一个系统如果能满足某一个标准的要求,就可以说它是一个什么系统。比如经常听一个系统是 posix 系统,就是说它可能满足 posix.1-1990 标准,这样写代码时就是标准可寻,会轻松一些。比如想写一个程序,要求到系统提供一些特殊支持,就可能很难做到广泛的移植。那么起码我们可以按照某一个标准写,比如我只用 posix.1 里规定的东西,那么只支持标准 C 的系统上肯定是不行了,不过在所有 POSIX 系统上编译都没问题。写的程序遵循越低的标准,可移植性就越强。讲 C 的书上一般,用的都是 C89 标准。所以应该在任何编译器上都能得到相同的結果(标准规定了未定义或未明确的不算)。