gpt4 book ai didi

c++ - 为什么链接器报告全局函数的多重定义符号而不是类静态方法

转载 作者:行者123 更新时间:2023-11-30 01:36:50 25 4
gpt4 key购买 nike

我知道有时链接器不会注意到一个符号在提供给链接器的所有输入(.obj 文件和静态 .lib 文件)中被多次定义。当然,有时链接器确实注意到一个符号被定义了两次并给出了一个错误。

但在下面的代码中,链接器确实注意到一个全局函数被定义了两次,同时没有注意到一个类静态方法被定义了两次。其他一切都是平等的。

这正常吗?有解释吗?同样,我知道链接器有时不会注意到第二个符号定义。问题是全局函数和类静态方法在多次定义链接器和符号方面有什么区别。

感谢您花时间提供帮助。如果我了解这里发生的事情,我会感觉好些。以下是编译并链接在一起的三个源文件。

翻译单元1.cpp:

// First definition of GlobalFunc()
void GlobalFunc() {std::cout << "GlobalFunc() in Translation Unit 1" << std::endl;}
void GlobalFunc_TransUnit1() {GlobalFunc();}

struct Foo
{
// First definition of Foo::ClassStaticFunc()
static void ClassStaticFunc() {std::cout << "Foo::ClassStaticFunc() in Translation Unit 1" << std::endl;}
};
void ClassStaticFunc_TransUnit1() {Foo::ClassStaticFunc();}

翻译单元2.cpp:

// Second definition of GlobalFunc()
void GlobalFunc() {std::cout << "GlobalFunc() in Translation Unit 2" << std::endl;}
void GlobalFunc_TransUnit2() {GlobalFunc();}

struct Foo
{
// Second definition of Foo::ClassStaticFunc()
static void ClassStaticFunc() {std::cout << "Foo::ClassStaticFunc() in Translation Unit 2" << std::endl;}
};
void ClassStaticFunc_TransUnit2() {Foo::ClassStaticFunc();}

Main.cpp - 从输出我们可以知道调用了哪个定义

void GlobalFunc_TransUnit1();
void GlobalFunc_TransUnit2();

void ClassStaticFunc_TransUnit1();
void ClassStaticFunc_TransUnit2();

int main(int argc, char** argv)
{
// This won't link (as expected).
// The linker reports that GlobalFunc() is defined twice.
GlobalFunc_TransUnit1();
GlobalFunc_TransUnit2();

// This links despite Foo::ClassStaticFunc() being defined twice.
// In the final executable, both ClassStaticFunc_TransUnit1() and
// ClassStaticFunc_TransUnit2() call the same Foo::ClassStaticFunc() -
// which happens to be the definition in TranslationUnit1.cpp
ClassStaticFunc_TransUnit1(); // Calls Foo::ClassStaticFunc() in TranslationUnint1.cpp
ClassStaticFunc_TransUnit2(); // Also calls Foo::ClassStaticFunc() in TranslationUnit1.cpp
}

最佳答案

参见 inline specifier .由于 ClassStaticFunc 完全在 struct 定义中定义,因此它隐式地是一个内联函数。允许在每个翻译单元中定义一次内联函数(而不是通常每个程序定义一次)。

如果这些定义不相同,则为未定义行为。因此,通常只有一个(头)文件包含定义,然后由需要它的每个翻译单元共享。

关于c++ - 为什么链接器报告全局函数的多重定义符号而不是类静态方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51110792/

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