c - 理解 C99 中的这个 "extern inline"调用

标签 c inline c99 linkage

所以我正在阅读一些代码并遇到这个小片段:

//file.h

extern inline void foo();

实现如下所示:

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

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

我的理解是inline规定编译器不会提示多个定义(根据 this link ),并且函数 may be eligible for inline substitution (作为类函数宏的替代)。

但在这种情况下,由于定义不在 header 中,因此内联函数仍然只有一个“副本”,因此它不符合包含 file.h 的文件中的内联替换条件。 (据我所知)。

(来自上面的第二个链接):

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); ),其中 inline f 的定义(例如, inline f(void){ return 42; } )也被提供。

顺序并不重要。

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

提供外部定义,就像

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

是的。

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

 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 标准的这个特定部分有点神秘,但提供了使用示例。)

关于c - 理解 C99 中的这个 "extern inline"调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56450337/

相关文章:

c - C 语言中 main(i) 的含义是什么?它是如何工作的? i 的值和类型是什么?

c - C 中无法释放内存

c++ - uint8_t、uint_fast8_t 和 uint_least8_t 之间的区别

c - 如果 if 语句返回相同的内容,C 编译器是否会合并它们?

c - 是否有 GCC 关键字允许结构重新排序?

c - 此代码的预期输出

c - scanf: "%[^\n]"跳过第二个输入但 "%[^\n]"没有。为什么?

css - 内联 UL 元素在 IE7 中不起作用

C++ 编译器不喜欢 "using INLINE = extern inline"

html - 使用详细信息标签时如何将光标从 "text"更改为 "default"