注意:当我在这个答案中谈到.c
个文件和.h
个文件时,我假设您的代码布局是正确的,即.c
个文件只包括.h
个文件.区别在于.h
文件可以包括在多个翻译单元中.
static inline void f(void) {}
和static void f(void) {}
没有实际区别.
在ISO C中,这是正确的.它们在行为上是相同的(当然,假设您在同一个TU中没有以不同的方式声明它们!)唯一的实际效果可能是使编译器进行不同的优化.
C中的inline void f(void) {}
不像C++那样工作.它在C语言中是如何工作的?extern inline void f(void);
到底是做什么的?
这是由this answer和this thread来解释的.
在ISO和C++中,你可以自由使用inline void f(void) {}
个头文件——尽管原因不同!
在ISO C中,它根本没有提供外部定义.在ISO C++中,它确实提供了一个外部定义;但是,C++有一个额外的规则(C没有),即如果一个inline
函数有多个外部定义,那么编译器会对其进行排序并挑选其中一个.
ISO C中.c
文件中的extern inline void f(void);
意味着在头文件中使用inline void f(void) {}
.它使函数的external definition在该转换单元中发出.如果不这样做,则没有外部定义,因此可能会出现链接错误(未指定是否有f
个链接的特定调用指向外部定义).
换句话说,在ISO C中,您可以手动选择外部定义的位置;或者通过到处使用static inline
来完全压制外部定义;但在ISO C++中,编译器选择外部定义的位置和位置.
在GNUC中,情况有所不同(下文将对此进行详细介绍).
为了进一步复杂化,GNU C++允许你在C++代码中写static inline
个extern inline
…我不想猜测它到底有什么作用
我从来没有在我的C程序中真正找到inline关键字的用法,而且当我在其他人的代码中看到这个关键字时,它几乎总是静电的inline
许多程序员不知道他们在做什么,只是把看起来可行的东西放在一起.这里的另一个因素是,您正在查看的代码可能是为GNU C编写的,而不是为ISO C编写的.
在GNU C中,plain inline
的行为与ISO C不同.它实际上发出一个外部可见的定义,因此,包含来自两个翻译单元的plain inline
函数的.h
文件会导致未定义的行为.
因此,如果编码器想要在GNU C中提供inline
优化提示,那么就需要static inline
.既然static inline
在ISO C和GNU C中都能工作,人们最终很自然地接受了它,并看到它似乎在工作,但没有给出错误.
,在这一点上,我看不到与静态的区别.
不同之处仅在于向编译器提供超大小速度优化提示的意图.对于现代编译器,这是多余的.