链接器实际上对多重定义的“内联"函数做了什么?

2022-01-11 00:00:00 c inline linker c++

在 C 和 C++ 中,具有外部链接的 inline 函数当然可以在链接时有多个可用定义,假设这些定义都(希望)相同.(我当然指的是使用 inline 链接规范声明的函数,而不是编译器或链接时间优化器实际内联的函数.)

In both C and C++, inline functions with external linkage can of course have multiple definitions available at link-time, the assumption being that these definitions are all (hopefully) identical. (I am of course referring to functions declared with the inline linkage specification, not to functions that the compiler or link-time-optimizer actually inlines.)

那么,常见的链接器在遇到函数的多个定义时通常会做什么?特别是:

So what do common linkers typically do when they encounter multiple definitions of a function? In particular:

  • 是否所有定义都包含在最终的可执行文件或共享库中?
  • 函数的所有调用是否都与同一个定义相关联?
  • 一个或多个 C 和 C++ ISO 标准是否要求回答上述问题?如果不是,大多数常见平台是否也这样做?

附:是的,我知道 C 和 C++ 是不同的语言,但它们都支持 inline,并且它们的编译器输出通常可以通过相同的链接器(例如 GCC 的 ld)链接,所以我相信他们在这方面没有任何区别.

P.S. Yes, I know C and C++ are separate languages, but they both support inline, and their compiler-output can typically be linked by the same linker (e.g. GCC's ld), so I believe there cannot be any difference between them in this aspect.

推荐答案

如果函数实际上是内联的,那么就没有什么可链接的了.只有当编译器出于某种原因决定不 内联扩展函数时,它才必须生成函数的外联版本.如果编译器为多个翻译单元生成函数的外联版本,您最终会得到多个目标文件,其中包含相同内联"函数的定义.

If the function is, in fact, inlined, then there's nothing to link. It's only when, for whatever reason, the compiler decides not to expand the function inline that it has to generate an out-of-line version of the function. If the compiler generates an out-of-line version of the function for more than one translation unit you end up with more than one object file having definitions for the same "inline" function.

行外定义被编译到目标文件中,并被标记,这样如果该名称的定义不止一个,链接器就不会报错.如果有多个,链接器只选择一个.通常是它看到的第一个,但这不是必需的,如果定义都相同,那没关系.这就是为什么对同一个内联函数有两个或多个不同定义是未定义行为的原因:没有选择哪个定义的规则.任何事情都有可能发生.

The out-of-line definition gets compiled into the object file, and it's marked so that the linker won't complain if there is more than one definition of that name. If there is more than one, the linker simply picks one. Usually the first one it saw, but that's not required, and if the definitions are all the same, it doesn't matter. And that's why it's undefined behavior to have two or more different definitions of the same inline function: there's no rule for which one to pick. Anything can happen.

相关文章