Linux C ++编译器(和链接器)如何决定将typeinfo放在哪里?

| 我在一个h文件中定义了一个类,并在作为一个lib的一部分的cpp中实现(我们将其称为libdef)。 我还有另外两个具有cpp文件(包含此h文件)的库。其中一个对此类进行dynamic_cast()(我们将其称为libdyn),另一个对此类进行new(我们将其称为libnew)。 似乎在这些库中的一个库中,有类型的typeinfo,而在另一个库中则没有:
user@machine> ld --cref libdef.so | grep -E \"typeinfo for MyClass\"
ld: warning: cannot find entry symbol _start; not setting start address
typeinfo for MyClass libdef.so

user@machine> ld --cref libnew.so | grep -E \"typeinfo for MyClass\"
ld: warning: cannot find entry symbol _start; not setting start address
typeinfo for MyClass libdef.so

user@machine> ld --cref libdyn.so | grep -E \"typeinfo for MyClass\"
ld: warning: cannot find entry symbol _start; not setting start address
typeinfo for MyClass libdyn.so
如您所见,libdef和libnew都使用libdef中的typeinfo,但是libdyn使用其自己的typeinfo。这是为什么?编译器/链接器如何确定是将typeinfo放在一个库中还是从另一个库中引用它? 我应该注意,libnew和libdyn都是使用-llibdef构建的。
user@machine> icpc -V
Intel(R) C++ Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version 12.0.0.084 Build 20101006
Copyright (C) 1985-2010 Intel Corporation.  All rights reserved.

user@machine> ld -V
GNU ld version 2.17.50.0.6-14.el5 20061020
Supported emulations:
 elf_x86_64
 elf_i386
 i386linux
经过一些检查后,这取决于lib的cpp文件是否“看到”了一个虚拟方法定义。 此代码不会导致typeinfo符号出现在库中:
class SomeClass { public: SomeClass(); virtual void func(); };
此代码将在库中生成typeinfo符号:
class SomeClass { public: SomeClass() {} virtual void func() {} };
如果存在,typeinfo符号将具有模糊的链接。     
已邀请:
G ++可能将该类的typeinfo定义为弱 符号,在需要它的每个目标文件中。对象之一
libdef
中的文件需要它,因为它是
vtable
中的一部分 由构造函数安装。和其中的目标文件之一 由于
dynamic_cast
,6ѭ需要它。我摔倒
libnew
确实是个新东西,但是可能不需要 (除非构造函数为内联)。无论如何,如果真的 是一个弱符号,只有一个定义是 并入最终的so或可执行文件;哪个是 未指定(但我怀疑它是链接器的第一个 遇到-与您所看到的相对应)。 在大多数情况下,这都不重要。 (例外是 您用
RTLD_LOCAL
dlopen
;做到这一点,并 如果在ѭ12中执行
dynamic_cast
可能会失败 而不是带有对象构造函数的对象。)     
正如其他人提到的,这取决于C ++实现。但是这里是对g ++的描述。 简而言之,在可能的情况下,g ++在转换单元中定义了类vtable和type_info,后者定义了该类的第一个非内联虚拟成员。     
我认为这将是编译器的实现细节。 通常(由于虚拟表本身就是实现细节),因此
virtual table
存储指向ѭ14pointer的指针,我认为typeinfo的存储位置是编译器的实现细节。很有可能它将ѭ15存储在声明该类的ѭ16中。     
我不知道您的编译器和链接器的实现细节,但是也许它足够聪明,不包含不需要的typeinfo?     

要回复问题请先登录注册