为什么C ++编译器合成函数(例如默认构造函数)内联?

时间:2013-10-30 02:43:50

标签: c++

我知道编译器在c ++中合成了函数,例如默认构造函数,复制构造函数.etc是隐式内联的,但我只是对为什么感到好奇?

并且,如果这些函数需要执行的任务太复杂而不适合内联怎么办?

1 个答案:

答案 0 :(得分:8)

第一个问题是inline真正意味着什么?这个问题的答案与实际内联没什么关系,更多的是与One Definition Rule有关。当编译器为内联函数生成代码时,它标记链接器的符号,以便知道在不同的转换单元中具有相同的符号是正常的。

考虑到这一点,答案很简单。如果函数不是inline并且编译器在两个不同的转换单元中生成它们,则将两个转换单元链接在一起将导致违反一个定义规则,该规则超出了程序员可以修复的范围。


上面的答案似乎并不清楚,当函数没有真正内联时会发生什么。从第一段开始:

  

当编译器为内联函数生成代码时,它会标记链接器的符号,以便知道在不同的转换单元中具有相同的符号是正常的。

编译器会在每个使用该函数的翻译单元中生成一个函数符号。然后链接器将使用标记(弱符号)来丢弃程序中除一个定义之外的所有定义。在许多情况下,即使函数代码实际内联,编译器也会生成inline函数的外联定义。

这与将函数标记为static(内部链接)不同,就好像它被标记为内部链接一样,所有这些定义都将保留在最终的可执行文件 *

* 有些链接器能够确定不同的符号完全相同并且会删除重复项,因此可能会将void f() { std::cout << "Hi\n"; }与void g(){std:合并: :cout&lt;&lt; “嗨,\ n”; } . Linkers that do this can also fold all of the static`功能在一起,但这是标准要求之外的优化。