当前位置:首页 > 单片机 > 程序喵大人
[导读]最近研究了一波RTTI,整理了一下知识点,在这里分享一下,下面是目录:RTTI是RunTimeTypeInformation的缩写,从字面上来理解就是运行时期的类型信息,它的主要作用就是动态判断运行时期的类型。一般在dynamic_cast和typeid中用到,例如父类B的指针转...

最近研究了一波RTTI,整理了一下知识点,在这里分享一下,下面是目录:









RTTI 是 Run Time Type Information 的缩写,从字面上来理解就是运行时期的类型信息,它的主要作用就是动态判断运行时期的类型。


一般在dynamic_cast和typeid中用到,例如父类B的指针转换子类A的指针,dynamic_cast会判断B究竟是不是A的父类,如果不是,会返回nullptr,相对于强转会更加安全。依据什么判断的呢?就是RTTI。







先看下面这段代码:


#include using std::cout;using std::endl;class Base{public: int a; int b; Base() { cout << this << " Base \n"; } virtual void func(){ cout << this << " hello Base \n"; }; void basefunc(){ cout << this << " hello basefunc \n"; }};class BaseBB{public: int d; int c; BaseBB() { cout << this << " BaseBB \n"; } virtual void func(){ cout << this << " hello BaseBB \n"; }};class Derive : public Base{public: Derive() { cout << this << " Derive \n"; } void func() override{ cout << this << " hello Derive \n"; }};int main(){ Derive *d = new Derive; typeid(d); d->func(); Base *b = static_cast(d); b->func(); b->basefunc(); Derive *b1 = dynamic_cast(b); Derive *b2 = static_cast(b); b1->func(); b2->func(); BaseBB *b3 = dynamic_cast(b); BaseBB *b4 = reinterpret_cast(b); cout << d << " " << b << " " << b1 << " " << b2 << " " << b3 << " " << b4 << endl; return 0;} 结果如下:


clang test_rtti.cc -std=c 11;./a.out
0x7fe80ac05920 Base 0x7fe80ac05920 Derive 0x7fe80ac05920 hello Derive 0x7fe80ac05920 hello Derive 0x7fe80ac05920 hello basefunc 0x7fe80ac05920 hello Derive 0x7fe80ac05920 hello Derive 0x7fe80ac05920 0x7fe80ac05920 0x7fe80ac05920 0x7fe80ac05920 0x0 0x7fe80ac05920 上面的代码是正常的一段使用多态的代码,同时也包含了子类指针转基类指针,基类指针转子类指针,从输出结果中可以看到,使用dynamic_cast进行不合理的基类子类指针转换时,会返回nullptr,而强转则不会返回nullptr,运行时肯定就会出现奇奇怪怪的错误,比较难排查。



如果在编译时加上-fno-rtti会怎么样?结果是这样:


clang test_rtti.cc -std=c 11 -fno-rtti
test_rtti.cc:60:5: error: use of typeid requires -frtti typeid(d); ^test_rtti.cc:65:18: error: use of dynamic_cast requires -frtti Derive *b1 = dynamic_cast(b); ^test_rtti.cc:69:18: error: use of dynamic_cast requires -frtti BaseBB *b3 = dynamic_cast(b); ^3 errors generated. 可以看到,加上了-fno-rtti编译时,使用typeid或dynamic_cast会报错,即添加-fno-rtti编译会禁止我们使用dynamic_cast和typeid。那为什么要禁止使用他们呢?



1. RTTI的空间成本非常高:每个带有vtable(至少一个虚拟方法)的类都将获得RTTI信息,其中包括类的名称及其基类的信息。此信息用于实现typeid运算符以及dynamic_cast。(大小问题大家可以自己编写代码验证一下)



2. 速度慢,运行时多判断了一层,性能肯定更慢一些。



tips:我这里又将typeid和dynamic_cast去掉重新编译,结果表明添加了-fno-rtti,还是可以正常使用多态,所以大家不用担心rtti的禁用会影响多态的使用。



都知道RTTI信息是存在于虚函数表中,而添加-fno-rtti后代表禁止了RTTI,那虚函数表中还会有rtti信息吗?




我这里使用clang的命令查看一下虚函数表:


clang -Xclang -fdump-vtable-layouts -stdlib=libc -fno-rtti -c test_rtti.cc
test_rtti.cc:51:17: warning: 'override' keyword is a C 11 extension [-Wc 11-extensions] void func() override ^Original map void Derive::func() -> void Base::func()Vtable for 'Derive' (3 entries). 0 | offset_to_top (0) 1 | Derive RTTI -- (Base, 0) vtable address -- -- (Derive, 0) vtable address -- 2 | void Derive::func()
VTable indices for 'Derive' (1 entries). 0 | void Derive::func() 通过结果可以看到,即使添加了-fno-rtti,虚函数表中还是会存在RTTI指针,但是我查看很多文档都说rtti会导致可执行文件的体积增大一些(毕竟-fno-rtti最大的目的就是为了减小代码和可执行文件的大小),所以我估计指针指向的块里面可能什么信息都没有,具体就不得而知了。





本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

Zephyr开源项目由Linux基金会维护,是一个针对资源受限的嵌入式设备优化的小型、可缩放、多体系结构实时操作系统(RTOS)。近年来,Zephyr RTOS在嵌入式开发中的采用度逐步增加,支持的开发板和传感器不断增加...

关键字: 嵌入式系统 软件开发 实时操作系统 Zephyr项目

在嵌入式系统和高可靠性软件开发中,静态代码分析已成为预防缺陷的关键手段。PC-Lint(现更名为Gimpel Lint)作为行业领先的C/C++静态分析工具,能够检测出编译器难以发现的隐式错误和编码规范违规。本文通过实战...

关键字: PC-Lint 软件开发 静态代码

在软件开发和系统运维中,内存泄漏是一个常见且棘手的问题。它会导致系统内存逐渐耗尽,进而影响应用程序的性能和稳定性,甚至引发系统崩溃。无论是用户态程序还是内核态模块,内存泄漏都可能悄然发生。本文将介绍如何结合 kmemle...

关键字: 软件开发 内存泄漏 kmemleak

在 AI 重构软件开发的浪潮中,编程助手领域掀起了一场激烈的资本与技术竞赛。

关键字: AI编程工具 Cursor 软件开发 编程助手 AI

智能时代的嵌入式系统离不开高性能、高效的软件和先进的软件开发方式。本文介绍了近期嵌入式软件开发的三个趋势:1)边缘计算作为一种在本地处理和分析数据的方式正在快速发展,边缘计算与人工智能的结合正将智能计算从以云为中心的模型...

关键字: 嵌入式系统 边缘计算 人工智能 虚拟化 软件开发

上海2025年1月13日 /美通社/ -- 1月3日,全球第三方检测认证机构TÜV南德意志集团(以下简称"TÜV南德")为上海电驱动股...

关键字: SPICE 软件开发 智能化 汽车行业

在软件开发过程中,调试是至关重要的一环。传统的调试方法往往需要在代码中插入打印语句(如printf),然后重新编译、部署和运行程序以查看输出信息。然而,这种方法不仅繁琐,而且在大型项目中,编译和部署过程可能非常耗时。为了...

关键字: GDB动态打印 软件开发

北京2024年12月10日 /美通社/ -- 12月5-6日,由CSDN联合高端IT咨询与教育平台Boolan联合主办的「2024全球C++及系统软件技术大会」在上海虹桥万豪大酒店隆重召开。在AI驱动软件开发迈向智能化的...

关键字: C++ 系统软件 ST 软件开发

作为软件开发中强大的生成式AI助手,Amazon Q Developer现在能够加速单元测试、文档生成、代码审查,以及运营排错,让开发者专注于更具创造力和有价值的工作上 北京2024年12月9日 /美通社/ --&nb...

关键字: DEVELOPER 亚马逊 软件开发 生成式AI

在MCU(微控制器单元)软件开发中,指针作为一种强大的工具,能够显著提高程序的灵活性和性能。然而,指针的使用也伴随着一系列潜在的风险和陷阱,特别是在资源受限的嵌入式系统中。本文将深入探讨MCU软件开发中使用指针时可能遇到...

关键字: MCU 软件开发 指针
关闭