【问题标题】:Defined virtual functions cause type_info dependence定义的虚函数导致 type_info 依赖
【发布时间】:2021-04-02 11:54:18
【问题描述】:

我有以下文件foobar.cc

struct Foo
{
  virtual int do_something() const = 0;
};

struct Bar : public Foo
{
  virtual int do_something() const override
  { return 1; }
};

Bar bar;

当我尝试用它构建一个共享对象时:

g++ -shared -fPIC foobar.cc -o foobar.so

nm foobar.so 输出行:

U _ZTVN10__cxxabiv117__class_type_infoE@@CXXABI_1.3
U _ZTVN10__cxxabiv120__si_class_type_infoE@@CXXABI_1.3

但是为什么呢?难道只有当其中一个虚函数不是纯函数或没有定义时才会出现这种情况?我知道我可以通过使用fno-rtti 进行编译来规避这种情况,但我正在尝试理解这种行为。

【问题讨论】:

  • Foo *fp = new Bar; Bar *bp = dynamic_cast<Bar*>(fp);.

标签: c++ gcc linker abi


【解决方案1】:

无论何时,您都会看到对这些 libstdc++ 符号的一些依赖:

  • 构造函数用于动态类类型(具有虚函数或虚基)。
  • 任何typeid 表达式,其操作数是类类型或类类型的表达式都会被编译(所以不在decltype 中,在从未使用过的内联函数中,等等)
  • 任何带有类类型操作数的throw 表达式都会被编译。

注意后两者根本不需要动态类类型。它们对其他类型的等价物也会导致对其他 libstdc++ type_info 相关符号的依赖。

这是type_info 继承信息存储方式的结果,在Itanium ABI (section 2.9.4 RTTI Layout) 之后。任何类类型的type_info 对象实际上具有最派生类型__cxxabiv1::__class_type_info__cxxabiv1::__si_class_type_info,它们继承std::type_info。但是由于std::type_info 是动态的,所以__class_type_info__si_class_type_info 也是动态的。这意味着这些类型的创建对象必须具有 vptr。这些 vptr 必须包含一个指向 std::type_info 对象的指针,这些对象表示实现类型 __class_type_info__si_class_type_info 本身。显然,这些对象是在没有按需链接的情况下创建的,但每个对象都包含一个指向要由 std::type_info::name() 返回的名称字符串的指针,这是您看到的从 libstdc++ 链接的实际“_ZTVN”符号。

【讨论】:

    猜你喜欢
    • 2015-04-17
    • 2017-06-01
    • 2014-07-26
    • 1970-01-01
    • 2013-09-18
    • 1970-01-01
    • 2019-07-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多