与链接相关的内联关键字的真正性质是什么?

What is the real nature of inline keyword in relation to linkages?

提问人:Rango 提问时间:8/3/2023 最后编辑:Jan SchultkeRango 更新时间:8/3/2023 访问量:208

问:

我有一个严重的问题,要用我的拙见来调和“内联概念”和“链接”:

  • 我听说我们可以用来访问“非静态实体” (就像一个不用静态键声明的实体)从其他 文件
    = 是!我明白了
    extern
  • 他们说我们可以用来制作一个函数或变量 出现在“头文件”中,以便可以跨多个访问它 翻译单位
    = 是!我明白了
    inline
  • 他们还说,“内联实体”可以有“内部或 外部链接“
    =我没明白

( 答:带内部联动的内联功能?- 这是我第一次听说具有“内部链接”的内联实体的地方:)

内联实体可以从多个翻译单元的任何地方访问,那么这是否意味着“内联实体”应该始终具有“外部链接”?

“内联实体”的意义何在,它可以跨多个翻译单元从任何地方访问,并具有“内部链接”?

任何答案或任何确认我在任何一点上都错了将不胜感激。

C++ 联动

评论

2赞 Eugene 8/3/2023
我从未听说过具有内部链接的内联实体。你在哪里找到的?
0赞 Rango 8/3/2023
stackoverflow.com/a/2398105/22196023 - 这是我第一次听到“内部链接”的地方
1赞 Pepijn Kramer 8/3/2023
内联关键字基本上意味着,链接器你可以选择这个函数的任何定义(实现)进行链接......作为开发人员,我承诺在多个翻译单元中可能遇到的所有版本实际上都是相同的版本。
5赞 user17732522 8/3/2023
你提到的问题是关于C的。关键字在 C++ 中的工作方式与在 C 中的工作方式不同。inline

答:

5赞 Jan Schultke 8/3/2023 #1

您链接的答案与 C 有关,其工作方式略有不同。但是,在任何一种语言中,都不会影响链接。inlineinline

inlineon 函数使其成为内联函数。默认情况下,任何自由函数都有外部链接,这基本上意味着在多个翻译单元中声明的所有函数都引用了相同的函数。 会使函数具有内部链接,这意味着每个翻译单元都有自己的.ffstaticf

// inline function with external linkage
inline void f() { }

// also an inline function with external linkage
extern inline void g() { }

// inline function with internal linkage
static inline void h() { }

namespace { // anonymous namespace
// also an inline function with internal linkage
inline void k() { }
}

内联实体可以从多个翻译单元的任何地方访问,那么这是否意味着“内联实体”应该始终具有“外部链接”?

函数不必是内联函数即可在多个 TU 中访问。 只是意味着它可以在多个 TU 中定义,而不仅仅是声明,这不会导致任何链接器错误(所有定义必须相同)。换言之,内联函数放宽了单一定义规则。是的,如上所述,自由函数默认具有外部链接,即使它们是.inlineinline

“内联实体”的意义何在,它可以跨多个翻译单元从任何地方访问,并具有“内部链接”?

没有。如果它可以在多个翻译单元中访问,那么它不应该有内部链接。内部链接的好处是,您可以在不同的 TU 中使用相同的名称以不同的方式定义它。 标头中是来自 C 的反模式,其动机是与 C++ 不同,如果函数未内联,链接器将在某个对象文件中查找定义,而该文件可能不存在。static inlineextern

// assuming all of the following are defined in a header ...

// C: if f() isn't inlined, we get linker errors
//    to solve this, declare an extern inline definition in some source file
// C++: if f() isn't inlined, this is okay; the linker will pick one of N definitions,
//      which are automatically generated in the non-inlined case
inline void f() {}

// C: if h() isn't inlined, duplicates get emitted into multiple TUs
// C++: same, but this is stupid and avoidable; don't use 'static inline'
static inline void h() {}