注意:在本答案中涉及到的
.c
文件和
.h
文件,我假设您已经正确编写了代码,即
.c
文件仅包括
.h
文件。区别是
.h
文件可以被多个翻译单元包含。
static inline void f(void) {}
和 static void f(void) {}
没有实际区别。
在 ISO C 中,这是正确的。它们的行为相同(当然,假设您没有在同一翻译单元中以不同方式重新声明它们!),唯一的实际影响可能是导致编译器进行不同的优化。
C 中的 inline void f(void) {}
不像 C++ 那样工作。在 C 中如何工作? extern inline void f(void);
实际上是做什么的?
这在这个回答和这个线程中有解释。
在 ISO C 和 C++ 中,您可以自由地在头文件中使用 inline void f(void) {}
,但原因不同!
在 ISO C 中,它根本不提供外部定义。在 ISO C++ 中,它提供了一个外部定义;但是,C++ 有一个额外的规则(C 没有),即如果有多个 inline
函数的外部定义,则编译器会解决这个问题并选择其中一个。
在ISO C的
.c
文件中,
extern inline void f(void);
的使用意味着需要在头文件中配对使用
inline void f(void) {}
。它会导致函数的外部定义在该翻译单元中被发出。如果不这样做,那么就没有外部定义,因此可能会出现链接错误(不确定是否任何特定调用
f
都链接到外部定义)。换句话说,在ISO C中,您可以手动选择外部定义的位置;或者通过在所有地方使用
static inline
来完全禁止外部定义;但在ISO C++中,编译器会选择是否以及外部定义将放置在哪里。
在GNU C中,情况有所不同(下文详细说明)。进一步复杂化问题的是,GNU C++允许您在C ++代码中编写
static inline
和
extern inline
...我不想猜测那会做什么。
许多程序员不知道自己在做什么,只是把一些看起来可以工作的东西组合在一起。另一个因素是你正在查看的代码可能是为GNU C编写的,而不是ISO C。
在
GNU C中,简单的
inline
与ISO C的行为不同。它实际上会发出一个外部可见的定义,因此在两个翻译单元中包含具有简单
inline
函数的
.h
文件将导致未定义的行为。因此,如果程序员想要在GNU C中提供
inline
优化提示,则需要使用
static inline
。由于
static inline
适用于ISO C和GNU C,自然而然的人们最终选择了它,并且看到它似乎可以工作而没有出现错误。
我认为静态内容和使用该标签没有区别。
这个标签只是为了提供速度优化提示给编译器,但在现代编译器中已经显得多余了。
inline
是有用的,而链接指向的是一个C++问题,这只会增加混淆。 - Antti Haapala -- Слава Україні