【发布时间】:2011-05-23 12:47:40
【问题描述】:
我在一个 h 文件中定义了一个类,并在一个 cpp 中实现,该 cpp 是一个 lib(我们称之为 libdef)的一部分。
我有另外两个库,它们的 cpp 文件包含这个 h 文件。其中一个对这个类执行 dynamic_cast()(我们称之为 libdyn),另一个对这个类执行 new(我们称之为 libnew)。
似乎在其中一个库中有类型的类型信息,但在另一个库中没有:
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 符号将具有模糊的链接。
【问题讨论】:
-
您似乎假设每种类型只有一个 typeinfo 对象......标准不保证这一点,它只保证如果有多个,它们将比较相等。
-
@Ben 问题是如果有多个,它们在 Linux 中不会比较相等(因为使用了地址比较)。如果您仅按照 gcc 的指示使用 lib,则不会发生这种情况,但我们仍然遇到问题,我正在尝试为我们的产品寻找一些解决方法。
-
通过“比较相等”,我不是指地址比较。我的意思是
operator=,它是为typeinfo类型的对象定义的。这是标准保证用于比较 typeinfo 实例的唯一机制。 -
@Ben 我不知道地址比较是否在 operator== 中实现,但我知道(好吧,在某处阅读)dynamic_cast() 在 Linux 上使用地址比较来确定类型相等性。
标签: c++ linux compiler-construction linker rtti