gpt4 book ai didi

c++ - Linux C++ 编译器(和链接器)如何决定将类型信息放在哪里?

转载 作者:太空狗 更新时间:2023-10-29 20:47:15 26 4
gpt4 key购买 nike

我在一个 h 文件中定义了一个类,并在作为一个库(我们称之为 libdef)的一部分的 cpp 中实现。

我有另外两个库有包含这个 h 文件的 cpp 文件。其中一个对这个类执行 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 的类型信息,但 libdyn 使用自己的类型信息。这是为什么?编译器/链接器如何决定是将类型信息放在一个库中还是从另一个库中引用它?

我应该注意到 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(); };

此代码将在库中生成一个类型信息符号:

class SomeClass { public: SomeClass() {} virtual void func() {} };

如果存在,typeinfo 符号将具有模糊的链接。

最佳答案

G++ 可能将类的类型信息定义为弱符号,在每个需要它的目标文件中。对象之一libdef 中的文件需要它,因为它是 vtable 的一部分由构造函数安装。和其中的目标文件之一libdyn 需要它,因为 dynamic_cast。我摔倒libnew 确实是一个新的,但是,它可能不需要它(除非构造函数是内联的)。无论如何,如果真的是一个弱符号,只有一个定义是合并到最终的so或可执行文件中;哪个是未指定(但我怀疑它是第一个链接器遭遇——对应于你所看到的)。

在大多数情况下,这些都不重要。 (异常(exception)是如果您正在使用 RTLD_LOCAL 调用 dlopen;这样做,然后如果 dynamic_cast.so 中执行,它可能会失败除了带有对象构造函数的那个​​。)

关于c++ - Linux C++ 编译器(和链接器)如何决定将类型信息放在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6097402/

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