Why does the ld linker allow multiple class definitions with the same methods?(为什么 ld 链接器允许使用相同方法定义多个类?)
问题描述
考虑这个文件,first.cpp
,包含一个类定义和使用:
Consider this file, first.cpp
, containing a class definition and use:
#include <iostream>
struct Foo
{
Foo(){ std::cout << "Foo()" << std::endl; }
~Foo(){ std::cout << "~Foo()" << std::endl; }
};
int main(){
Foo f;
return 0;
}
另一个,second.cpp
,包含一个冲突的类定义:
and another, second.cpp
, containing a conflicting class definition:
#include <iostream>
struct Foo
{
Foo();
~Foo();
};
Foo::~Foo(){ std::cout << "wrong ~Foo()" << std::endl; }
当定义了两个具有相同名称的函数时,链接器会抱怨重复符号,但是这些具有重复类方法的文件编译时不会出错.
The linker complains about duplicate symbols when there are two functions with the same names defined, but these files with duplicate class methods compile without an error.
我用这些命令编译:
$ g++ -c second.cpp -o second
$ g++ second first.cpp -o first
对第二个 g++
调用的参数重新排序不会改变输出.
Reordering the arguments to the second g++
call doesn't change the output.
当 first
运行时,输出如下:
And when first
is run, this is the output:
$ ./first
Foo()
wrong ~Foo()
为什么链接器允许重复的类方法?如果显然允许,为什么会打印 wrong ~Foo()
?
Why does the linker allow duplicate class methods? If it's apparently allowed, why is wrong ~Foo()
printed?
推荐答案
再次,未定义的行为.您的程序对 Foo
的析构函数有多个定义,这意味着它违反了 ODR.程序是错误的,任何事情都可能发生.
Again, Undefined Behavior. Your program has multiple definitions for the destructor of Foo
, which means that it is in violation of the ODR. The program is wrong and anything can happend.
为什么链接器不接收它?当一个函数在类定义中定义时,它是隐式的inline
.编译器通常将这些函数标记为弱符号".然后链接器获取所有翻译单元并尝试解析符号.如果需要,链接器将删除弱符号(即,如果符号已在其他地方定义).
Why does the linker not pick it up? When a function is defined inside the class definition, it is implicitly inline
. Compilers usually mark those functions as 'weak symbols'. The linker then gets all translation units and tries to resolve the symbols. Weak symbols will be dropped by the linker if needed (i.e. if the symbol is already defined somewhere else).
从程序的实际输出来看,编译器似乎实际上并没有内联对构造函数的调用,因此在运行时将其分派给链接器留下的符号(非弱符号)
As of the actual output of the program, it looks like the compiler did not actually inline the call to the constructor and thus dispatched at runtime to the symbol that was left by the linker (the non-weak one)
为什么链接器允许有重复的方法?
Why linker allows to have duplicate methods?
因为所有(但最多一个)都是弱符号(即 inline
)
Because all (but at most one) are weak symbols (i.e. inline
)
为什么在这种情况下会打印错误的~Foo()?
Why, in this case, wrong ~Foo() is printed?
因为调用没有内联,并且链接器丢弃了弱符号
Because the call was not inlined, and the linker dropped the weak symbol
这篇关于为什么 ld 链接器允许使用相同方法定义多个类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:为什么 ld 链接器允许使用相同方法定义多个类?
基础教程推荐
- 如何C++使用模板特化功能 2023-03-05
- C++详细实现完整图书管理功能 2023-04-04
- C利用语言实现数据结构之队列 2022-11-22
- 详解c# Emit技术 2023-03-25
- C语言 structural body结构体详解用法 2022-12-06
- C++中的atoi 函数简介 2023-01-05
- C语言基础全局变量与局部变量教程详解 2022-12-31
- C++使用easyX库实现三星环绕效果流程详解 2023-06-26
- C/C++编程中const的使用详解 2023-03-26
- 一文带你了解C++中的字符替换方法 2023-07-20