gpt4 book ai didi

c++ - 链接器如何决定使用哪个实现

转载 作者:行者123 更新时间:2023-11-30 01:55:42 34 4
gpt4 key购买 nike

假设我们有以下文件:

//foo.h
class Foo
{
public:
void foo()
{
//Great code here
}
};

//foo1.cpp
#include "foo.h"

void Foo1()
{
Foo f1;
f1.foo();
}

//foo2.cpp
#include "foo.h"

void Foo2()
{
Foo f2;
f2.foo();
}

当我将它们分开编译时,它们会生成两个对象:Foo1.o Foo2.o。当我将它们链接在一起时,它们会完美地链接在一起。

现在,如果我为两者转储符号表,似乎在两个编译单元中实现了 Foo::foo 函数。

_ZN3Foo3fooEv

现在,链接器如何区分使用哪个实现?

最佳答案

Mats Petersson 的回答完全正确,但我会用不同的覆盖面用我自己的话来解释......

当您编译 C++ 代码时,您一次编译一个翻译单元...每个翻译单元通常包含一个实现文件(例如 .cpp/.cc 或您选择的任何文件)命名它)和它包含的头文件,编译器生成一个 .o 文件。当编译器看到您的 foo.hFoo::foo() 的定义时,它会认为它是一个名义上内联函数,因为函数体出现在类内部。因此,编译器可能会或可能不会在调用点实际内联函数 - 该决定将取决于函数的大小/复杂性以及编译器的启发式和选项。因此,对于两个翻译单元,Foo::foo 可能仍会在 .o 中作为单独的外联函数结束。

因为函数名义上是内联的,编译器需要确保该符号被标记为“弱符号”(确切的术语可能因操作系统/工具链而异——这是低于 C++ 标准级别的实现细节)——参见http://en.wikipedia.org/wiki/Weak_symbol

当链接对象中具有相同的弱符号时,一个拷贝的代码将被保留,而其他拷贝将被丢弃。因此,两个 .o 文件都可能具有该函数(尽管由于类中的定义,它名义上是内联的),但是从 .o 链接的可执行文件只有一个拷贝.

关于c++ - 链接器如何决定使用哪个实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20466481/

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