当前位置: 首页 > 知识库问答 >
问题:

定义的虚函数导致type_info依赖

米景辉
2023-03-14

我有以下文件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进行编译来规避这个问题,但我正在尝试理解这种行为。

共有1个答案

澹台举
2023-03-14

您将看到这些libstdc++符号的一些依赖关系,只要:

  • 构造函数ODR用于动态类类型(具有虚函数或虚基)。
  • 任何操作数为类类型或类类型表达式的TypeID表达式都将被编译(因此不在DeclType中,也不在从未使用过的内联函数中,等等)
  • 编译具有类类型操作数的任何throw表达式。

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

这是按照Itanium ABI(第2.9.4节RTTI布局)存储type_info继承信息方式的结果。任何类类型的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”符号。

 类似资料:
  • 我有以下firebase云功能: 当该函数被激发时,它应该从对的异步await调用中获取alert_ad的值。然而,当运行该程序时,我在云函数日志中发现一个错误,说明它是未定义的。我不知道为什么会这样。 我如何测试或记录这一点,以确保async/await实际上获得了一个值?

  • /subsystem=elytron/dir-context=pepdircontext:add(url=“ldap://127.0.0.1:10389”,principal=“uid=admin,ou=system”,credential-reference={clear-text=“secret”}) /subsystem=elytron/ldap-realm=pepdircontext,id

  • 问题内容: 我有一个简单的函数,它仅将翻译后的消息从服务器返回到客户端。但是,当我将结果传递给var时,结果显示为未定义。 结果- >未定义(错误) 当我查看标题时,它会给我: 为什么我仍然得到不确定的结果? 问题答案: 您可以将回调函数传递给该函数 然后调用:

  • Lua 使用关键字 function 定义函数,语法如下: function function_name (arc) -- arc 表示参数列表,函数的参数列表可以为空 -- body end 上面的语法定义了一个全局函数,名为 function_name. 全局函数本质上就是函数类型的值赋给了一个全局变量,即上面的语法等价于 function_name = function (arc)

  • 在 Python 中,定义函数使用 def 语句。一个函数主要由三部分构成: 函数名 函数参数 函数返回值 让我们看一个简单的例子: def hello(name): return name >>> r = hello('ethan') >>> r 'ethan' 在上面,我们定义了一个函数。函数名是 hello;函数有一个参数,参数名是 name;函数有一个返回值,name。 我们也可以

  • 我有一个Spring服务正在检查数据库条目。为了最小化我的存储库调用,两个find方法都是“@cacheable”。但是,当我尝试初始化我的服务bean,而我的配置类有一个CacheManager bean定义时,我会得到以下NosuchBeanDefinitionException: 如果我取出CacheManager bean定义,我可以初始化我的服务bean,它运行时没有任何问题和缓存! 下