C99 inline
一直以来都用C++用得比较多,这个学期作操做系统的课设用回了C,结果一波內联函数竟然连接不过去……查了查资料,C99引入的inline和C++的inline语义区别是很大的,我算是踩了这个坑。 C++的inline除了建议编译器把函数内容内联之外,主要的做用就是可以让你把一个函数的定义在不一样的编译单元里重复,而不会报连接错误。C99的inline则否则,它的语义是:app
Any function with internal linkage can be an inline function. For a function with external linkage, the following restrictions apply: If a function is declared with an inline function specifier, then it shall also be defined in the same translation unit. If all of the file scope declarations for a function in a translation unit include the inline function specifier without extern, then the definition in that translation unit is an inline definition. An inline definition does not provide an external definition for the function, and does not forbid an external definition in another translation unit. An inline definition provides an alternative to an external definition, which a translator may use to implement any call to the function in the same translation unit. It is unspecified whether a call to the function uses the inline definition or the external definition.ide
大概能够总结为如下几点:函数
- Internal linkage的函数总能够用inline修饰,C代码中常见的static inline用法就是从这来的。
- 在某个编译单元中,若是某个inline函数的任意一个declaration都没有用extern修饰,那么这个编译单元中的该函数定义称为内联定义。编译器能够选择使用内联定义(即接受建议),也能够不使用该定义,此时至关于这个定义不存在(即这个函数的调用须要连接其余编译单元的符号)。
- 内联定义其实是提供了对外部连接函数的一个“替代方案”。好比你在a.c中已经有了函数foo的定义,可是你在b.c中又给了个foo的内联定义,那么编译器可能会用b.c中给的内联定义,也可能视之不见。
因此C语言的inline语义的正确使用方法应该有下面三种:spa
static inline,不解释:操作系统
// a.h static inline int func(int x) { /* ... */ }
这样作能够模仿C++的inline语义:rest
// a.h inline int func(int x) { /* ... */ } // a.c extern int func(int x);
提供函数的“内联版本”,由编译器进行选择:code
// a.h int func(int x); //a.c int func(int x) { /* implementation [1] */ } // b.c inline int func(int x) { /* implementation [2] */ } void A(void) { //... i = func(j); //... }
最后一种用法中,implementation [1]和implementation [2]能够是不同的。也就是说,咱们能够为已有的函数提供一个“内联版本”,这个版本不须要和原版相同。至于用哪一个,则由编译器决定。ci