我知道编译器在c ++中合成了函数,比如默认构造函数,复制构造函数.etc是隐式内联的,但我只是好奇为什么?
如果这些功能需要完成的任务太复杂而不适合内联怎么办?
第一个问题是它真正意味着inline什么?这个问题的答案与实际内联没什么关系,更多的是与One Definition Rule有关.当编译器为内联函数生成代码时,它标记链接器的符号,以便知道在不同的转换单元中具有相同的符号是正常的.
考虑到这一点,答案很简单.如果函数不是inline,并且编译器在两个不同的转换单元中生成它们,则将两个转换单元链接在一起将导致违反一个定义规则,该规则超出了程序员可以修复的范围.
看起来上面的答案并不清楚当函数没有真正内联时会发生什么.从第一段开始:
当编译器为内联函数生成代码时,它标记链接器的符号,以便知道在不同的转换单元中具有相同的符号是正常的.
编译器会在使用该函数的每个转换单元中生成函数符号.然后链接器将使用标记(弱符号)来丢弃程序中除一个定义之外的所有定义.在许多情况下,inline即使函数代码实际内联,编译器也会生成函数的外联定义.
这不同于将函数标记为static(内部链接),就好像它被标记为内部链接一样,所有这些定义都将保留在最终的可执行文件中*
*有一些链接器能够确定不同的符号完全相同并将删除重复项,因此它可能void f() { std::cout << "Hi\n"; }与void g(){std :: cout <<"Hi \n" 合并; } . Linkers that do this can also fold all of thestatic`函数一起使用,但这是标准强制要求之外的优化.
| 归档时间: |
|
| 查看次数: |
214 次 |
| 最近记录: |