c++ 内联对函数的链接有什么影响?

ogq8wdun  于 2024-01-09  发布在  其他
关注(0)|答案(2)|浏览(139)

我正在阅读ODR,正如规则所说,我尝试了以下操作...
file1.cpp

  1. #include <iostream>
  2. using namespace std;
  3. inline int func1(void){ return 5; }
  4. inline int func2(void){ return 6; }
  5. inline int func3(void){ return 7; }
  6. int sum(void);
  7. int main(int argc, char *argv[])
  8. {
  9. cout << func1() << endl;
  10. cout << func2() << endl;
  11. cout << func3() << endl;
  12. cout << sum() << endl;
  13. return 0;
  14. }

字符串
file2.cpp

  1. inline int func1(void) { return 5; }
  2. inline int func2(void) { return 6; }
  3. inline int func3(void) { return 7; }
  4. int sum(void) { return func1() + func2() + func3(); }


它就像规则说的那样工作。我可以有多个内联函数的定义。

  • 非内联函数链接和内联函数链接之间有什么区别?
  • 链接器如何区分这两种情况?
tpxzln5u

tpxzln5u1#

创建一个函数inline做了两件事(第二点与你的问题更相关):
1.这是程序员对编译器的一个建议,可以通过内联扩展来快速调用这个函数。粗略地说,内联扩展类似于将内联函数当作宏处理,通过其主体的代码来扩展对它的每个调用。这是一个 * 建议 * -编译器可能不会(有时不能)执行这样的各种优化。
1.它将函数的作用域指定为转换单元的作用域。(或者因为它是写在它里面的,或者因为它#include是写在它里面的一个头,在这种情况下,预处理器基本上是这样做的)。现在编译foo.cpp,还可能包含具有相同签名的inline函数的其他bar.cpp(可能是同一个;可能是由于两个#include使用相同的头)。当链接器链接两个目标文件时,它不会被认为违反ODR,因为inline指令使文件的每个副本都在其翻译单元(有效地通过编译它创建的目标文件)的本地。这不是一个建议,它是 * 绑定 *。
这两件事结合在一起并不是巧合。最常见的情况是一个inline函数出现在几个源文件的头文件#include d中,可能是因为程序员想要请求快速内联扩展。这需要执行单元局部性规则,这样就不会出现链接器错误。

5hcedyr0

5hcedyr02#

非内联函数链接和内联函数链接之间有什么区别?
没有;请参见[dcl.inline]注解1
关键字inline对函数的链接没有影响。“
然而,inline导致单一定义规则(ODR)的放松:
对于具有多个转换单位中的定义的任何可定义项D

  • 如果D是一个非内联非模板化函数或变量,或者
  • 如果不同翻译单元中的定义不满足以下要求,

程序格式不正确; [...]

  • [基本.定义.odr] p14
    换句话说,一个内联函数可以在多个翻译单元(即.cpp文件)中定义,而不会出现链接器错误。这是因为链接器选择了一个定义,而忽略了所有其他定义。换句话说,一个内联函数是一个weak symbol
    然而,[basic.def.odr]定义了大量的限制。也就是说,内联函数需要在任何地方都被定义为 * 完全 * 相同的,逐个标记的。例如:
  1. // a.cpp
  2. inline int foo() { return 0; }
  3. // b.cpp
  4. inline long foo() { return 0; }

字符串
这样的程序是错误的,不需要诊断,因为定义是不相同的。确保所有定义都相同的最简单的方法是将它们放在一个标题中。标题被复制并粘贴到#include的翻译单元中,这样就不太可能出错。另请参阅Why do inline functions have to be defined in a header file?
“内联”怎么样?
编译器将内联函数作为优化,而不管是否使用inline。只要函数的定义对编译器可见,它就会执行此优化。
inline只是提供了一个提示,有助于启发式算法决定是否应该进行内联。

展开查看全部

相关问题