了解 C99 中的这个 "extern inline" 调用

Understanding this "extern inline" call in C99

所以我正在阅读一些代码,运行 阅读这个小片段:

//file.h

extern inline void foo();

实现如下所示:

//file.c
MyType_t instance;
inline void foo()
{
    instance.someField++;
}

也许我误解了什么,但在我看来作者打算有一个外部可见的函数,它也是 inline(我相信默认情况下它有内部 linkage ).因为它是一个微小的修饰函数,我认为其目的是利用内联替换来避免函数开销(这是有道理的,因为它在嵌入式平台上运行)。但是这段代码真的符合内联替换条件吗?

我的理解是 inline 规定编译器不会抱怨多个定义(根据 this link), and that the function may be eligible for inline substitution(作为 function-like 宏的替代方法)。

虽然在这种情况下,因为定义不在header中,所以内联函数仍然只有一个"copy",所以它不符合在文件中进行内联替换的条件包括 file.h (据我所知)。

(来自上面第二个link):

the compiler must at least have seen a definition of the function. But if you have a classical big C project with functions that are implemented in different compilation units the compiler can’t do that integration for you. So you’d have to put the implementation of such candidate functions in header files.

因此,只剩下 属性 编译器不会抱怨多重定义的符号,因此它可能在不同的编译单元中有不同的定义。虽然在这种情况下并非如此,但符号仅定义一次以供记录。

所以我的问题的症结在于:我得出的结论是这个内联并没有比这段代码更好地发挥作用:

//file.h
extern void foo();

//file.c
MyType_t instance;
void foo()
{
    instance.someField++;
}

如果作者想让它符合内联替换的条件,解决方案会是 put the inline declaration and function body in the header 吗?

C99 内联函数不像 C++ 内联函数。

它们没有合并。如果你不这样做,你应该提供一个外部定义 static.

内联函数 f 的方法是提供 extern 声明(例如,int f(void);extern int f(void);extern inline int f(void); ) 在翻译单元中,其中还提供了 finline 定义(例如,inline f(void){ return 42; })。

顺序不重要。

inline int f(void) { return 42; }
int f(void);

一样提供外部定义
int f(void);
inline int f(void) { return 42; }

会。

只有内联 declarations/definitions 而没有外部声明的翻译单元将不会提供外部定义:

 inline int f(void); 
//^if an inline decl is present a definition MUST follow or else you get a diagnostic
 inline int f(void) { return 42; }
 inline int f(void);  //a pointless but legal redeclaration

通常您会像示例中那样在 header 中有一个内联定义,然后要实例化它,您将包含 header 并提供外部声明。在声明中包含 externextern inline 在技术上是不必要的,但它清楚地表明该声明的目标是实例化内联函数的外部定义。

更多信息请见 6.7.4p7。 (我发现 C 标准的这个特定部分有点神秘,但提供了用法示例。)