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

标签 c++ visual-c++

我知道有时链接器不会注意到一个符号在提供给链接器的所有输入(.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/

相关文章:

C++ 用迭代器初始化 vector

c++ - 为什么 auto 的推论不同?

visual-c++ - CreateProcess 和 CreateProcessA 有什么区别?

linux - visual c++ for linux 停止(tty 输入)

c++ - 更改 .cpp、.h 文件的 Visual Studio 默认路径

c++ - Visual Studio C++ 2010 错误 LNK2019 : unresolved external symbol

c++ - 将友元与继承结合起来访问私有(private)数据成员是否可以

c++ - 这个用于计算指数的递归代码的运行时间是多少?

c++ - 带有 unique_ptr 的 CRTP 导致段错误

c++ - 从 unsigned char* 到 const wchar_t* 的转换