简体   繁体   English

跨多个 C++ 翻译单元的内联函数

[英]Inline functions across multiple C++ translation units

I recently learnt about inline functions in C++.我最近学习了 C++ 中的内联函数。 I understand how they work (in terms of expanding the code instead of making jumps etc), however I'm a little confused regarding how I should use them when it comes to multiple translation units / *.cpp files.我了解它们是如何工作的(在扩展代码而不是进行跳转等方面),但是当涉及到多个翻译单元 / *.cpp 文件时,我对如何使用它们感到有些困惑。

I've read that, as a rule of thumb, I should contain the definition of the function itself inside a header file (and not just its declaration) and then include the header file in each translation unit I aim to use said inline function.我已经读过,根据经验,我应该在头文件中包含函数本身的定义(而不仅仅是它的声明),然后在我打算使用所述内联函数的每个翻译单元中包含头文件。 That is not a problem for an inline function, since it will just exist standalone on each translation and expand itself when/if needed (decided by the compiler) [ please correct me if I am wrong regarding any of this!]对于内联函数来说,这不是问题,因为它只会在每个翻译中独立存在,并在需要时/如果需要(由编译器决定)进行扩展[如果我对此有任何错误,请纠正我!]

However, I also read that during link time, even if the definition of an inline function itself is not present in the header file, the linker can find its definition and expand it if needed.但是,我也读到在链接期间,即使头文件中不存在内联函数本身的定义,链接器也可以找到它的定义并在需要时扩展它。 But how would the linker be able to expand a function from a different translation unit?但是链接器如何能够从不同的翻译单元扩展一个函数呢? And if that's the case, why would I need to include the definition of the function in each translation unit (through header files)?如果是这样,为什么我需要在每个翻译单元中包含函数的定义(通过头文件)?

The inline keyword in front of a function was only an optional indicator for the compiler that inline is preferred.函数前面的inline关键字只是编译器首选 inline 的可选指示符。 Modern compilers don't care about the inline keyword when it comes to code inlining.现代编译器在代码内联时并不关心inline关键字。

The important meaning about inline is "multiple definitions are permitted", member functions definitions implicitly inline if they are in the body of the class. inline的重要含义是“允许多个定义”,如果成员函数定义在类的主体中,则隐式内联。

You need inline if you have the same function definition in multiple translation units (eg if you place the function definition in a header, and that header is included by multiple cpp files)如果您在多个翻译单元中具有相同的函数定义,则需要inline (例如,如果您将函数定义放在一个标题中,并且该标题包含在多个 cpp 文件中)

I've read that, as a rule of thumb, I should contain the definition of the function itself inside a header file (and not just its declaration) and then include the header file in each translation unit I aim to use said inline function.我已经读过,根据经验,我应该在头文件中包含函数本身的定义(而不仅仅是它的声明),然后在我打算使用所述内联函数的每个翻译单元中包含头文件。 That is not a problem for an inline function, since it will just exist standalone on each translation and expand itself when/if needed (decided by the compiler)这对于内联函数来说不是问题,因为它只会在每个翻译中独立存在,并在需要时/如果需要(由编译器决定)扩展自身

Placing a function definition in the header makes it easier for the toolchain to do inlining because it knows its definition when it is used and can perform the inlining in the compilation step.将函数定义放在头文件中使工具链更容易进行内联,因为它在使用时知道其定义并且可以在编译步骤中执行内联。 Having a function definition in multiple translation units requires it to be marked with inline .在多个翻译单元中有一个函数定义需要用inline标记。

However, I also read that during link time, even if the definition of an inline function itself is not present in the header file, the linker can find its definition and expand it if needed.但是,我也读到在链接期间,即使头文件中不存在内联函数本身的定义,链接器也可以找到它的定义并在需要时扩展它。 But how would the linker be able to expand a function from a different translation unit?但是链接器如何能够从不同的翻译单元扩展一个函数呢?

A toolchain could do link-time optimization (like inlining) for any function (no matter if their definition is known at compile time) for which the definition is known at linking time (static linking), but link-time optimizations tend to - at least in the past - not as efficient as compile-time optimizations.工具链可以对链接时(静态链接)的定义已知的任何函数(无论它们的定义在编译时是否已知)进行链接时优化(如内联),但链接时优化倾向于 - 在至少在过去 - 不如编译时优化有效。

The problem with link-time optimizations is, that toolchain either needs to keep track of the additional information provided by the source code that is helpful for optimizations or needs to rely on possible less powerful the strategies you can apply on the binaries.链接时优化的问题是,工具链要么需要跟踪源代码提供的有助于优化的附加信息,要么需要依赖可能不太强大的策略,您可以在二进制文件上应用。

If you have a main.cpp that looks like this:如果您有一个如下所示的main.cpp

int sum(int a, int b) {
  return a+b;
}

int main() {
  std::cout << sum(3,4) << std::endl;
  return 0;
}

Any modern compiler will inline that code (or in that case event completely optimize it aways to std::cout << 7 << std::endl; ).任何现代编译器都会内联该代码(或者在这种情况下,事件将其完全优化为std::cout << 7 << std::endl; )。

Also this will be fine and inlined/optimized:这也将是好的和内联/优化:

sum.h总和

int sum(int a, int b) { // no inline keyword in front of the function
  return a+b;
}

main.cpp主程序

#include "sum.h"
int main() {
  std::cout << sum(3,4) << std::endl;
  return 0;
}

But as soon as you use #include "sum.h" in multiple cpp files and link those translation units together you get a problem and need to use inline .但是一旦您在多个 cpp 文件中使用#include "sum.h"并将这些翻译单元链接在一起,您就会遇到问题并且需要使用inline inline in front of a function is nowadays really only there to tell the linker that having the same definition in multiple translations units is your intent.函数前面的inline现在实际上只是告诉链接器在多个翻译单元中具有相同的定义是您的意图。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM