gpt4 book ai didi

c++ - C++ 链接器是否会自动内联函数(没有 "inline"关键字,在 header 中没有实现)?

转载 作者:IT老高 更新时间:2023-10-28 22:23:29 28 4
gpt4 key购买 nike

C++ 链接器是否会自动内联“传递”函数,这些函数未在 header 中定义,也未通过 inline 关键字明确要求“内联”?

例如,以下情况经常发生,并且应该总是受益于“内联”,似乎每个编译器供应商都应该“自动”通过“通过链接器内联”(在可能的情况下):

//FILE: MyA.hpp
class MyA
{
public:
int foo(void) const;
};

//FILE: MyB.hpp
class MyB
{
private:
MyA my_a_;
public:
int foo(void) const;
};

//FILE: MyB.cpp
// PLEASE SAY THIS FUNCTION IS "INLINED" BY THE LINKER, EVEN THOUGH
// IT WAS NOT IMPLICITLY/EXPLICITLY REQUESTED TO BE "INLINED"?
int MyB::foo(void)
{
return my_a_.foo();
}

我知道 MSVS 链接器将通过其链接时间代码生成 (LTGCC) 执行一些“内联”,并且 GCC 工具链还支持 链接时间优化 (LTO)(参见:Can the linker inline functions?)。

此外,我知道在某些情况下不能“内联”,例如当实现对链接器不“可用”时(例如,跨共享库边界,其中发生单独的链接)。

但是,如果将代码链接到不跨越 DLL/共享库边界的单个可执行文件,我希望编译器/链接器供应商 自动内联函数,作为一种简单而明显的优化(对性能和大小都有好处)?

我的希望是不是太天真了?

最佳答案

这是对您的示例的快速测试(使用简单地返回 42MyA::foo() 实现)。所有这些测试都是针对 32 位目标的 - 使用 64 位目标可能会看到不同的结果。还值得注意的是,使用 -flto 选项 (GCC) 或 /GL 选项 (MSVC) 会导致完全优化 - 无论是 MyB::foo() 被调用,它被简单地替换为 42

使用 GCC (MinGW 4.5.1):

gcc -g -O3 -o test.exe myb.cpp mya.cpp test.cpp

对 MyB::foo() 的调用没有被优化掉。 MyB::foo() 本身被略微优化为:

Dump of assembler code for function MyB::foo() const:
0x00401350 <+0>: push %ebp
0x00401351 <+1>: mov %esp,%ebp
0x00401353 <+3>: sub $0x8,%esp
=> 0x00401356 <+6>: leave
0x00401357 <+7>: jmp 0x401360 <MyA::foo() const>

入口序言留在原地,但立即撤消(leave 指令),代码跳转到 MyA::foo() 以完成真正的工作。然而,这是 编译器(不是链接器)正在做的优化,因为它意识到 MyB::foo() 只是简单地返回任何 MyA::foo() 返回。我不确定为什么会留下序幕。

MSVC 16(来自 VS 2010)的处理方式略有不同:

MyB::foo() 以两次跳转结束 - 一次跳转到某种“thunk”:

0:000> u myb!MyB::foo
myb!MyB::foo:
001a1030 e9d0ffffff jmp myb!ILT+0(?fooMyAQBEHXZ) (001a1005)

而 thunk 只是跳转到 MyA::foo():

myb!ILT+0(?fooMyAQBEHXZ):
001a1005 e936000000 jmp myb!MyA::foo (001a1040)

再次 - 这主要(完全?)由编译器执行,因为如果您查看链接之前生成的目标代码,MyB::foo() 被编译为一个简单的跳转到 MyA::foo().

因此,将这一切归结为 - 看起来在没有显式调用 LTO/LTCG 的情况下,今天的链接器不愿意/无法执行完全删除对 MyB::foo() 的调用的优化,即使 MyB::foo() 是一个简单的跳转到 MyA::foo()

所以我想如果你想优化链接时间,请使用 -flto(用于 GCC)或 /GL(用于 MSVC 编译器)和 /LTCG (用于 MSVC 链接器)选项。

关于c++ - C++ 链接器是否会自动内联函数(没有 "inline"关键字,在 header 中没有实现)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7223993/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com