[导读]最近研究了一波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
智能时代的嵌入式系统离不开高性能、高效的软件和先进的软件开发方式。本文介绍了近期嵌入式软件开发的三个趋势: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
软件开发
指针
南京2024年10月29日 /美通社/ -- 数睿数据在企业数字化转型中,基于每个企业的情况进行调研、分析。每个企业数字化建设程度均不一致,部分企业建设了不少应用系统,也有部分企业尚未开展信息化建设。 针对各企业的特点...
关键字:
代码
数字化建设
软件开发
BSP
在软件开发中,没有什么比获得一个几乎没有文档并且需要维护它的代码库更具挑战性的了。文档不仅告诉工程师特定函数或变量的作用,而且还演示和传达了软件以特定方式实现的原因。在构建软件时会做出数百万个决策,对于嵌入式开发人员来说...
关键字:
嵌入式
软件开发
上海2024年10月18日 /美通社/ -- 国际第三方检测认证机构TÜV南德意志集团(以下简称"TÜV南德")近日授予兆松科技(武汉...
关键字:
ISO
编译器
软件开发
汽车行业
在计算机系统发展的早期时代(20世纪60年代中期以前),通用硬件相当普遍﹐软件却是为每个具体应用而专门编写的。这时的软件通常是规模较小的程序,编写者和使用者往往是同一个(或同一组)人。这种个体化的软件环境,使得软件设计通...
关键字:
软件
软件开发
实时测试是软件开发生命周期的一个关键部分,涉及实时测试软件应用程序的可靠性和功能。这包括模拟实时环境或场景,以验证软件应用程序在各种负载条件下的性能。因此,实时测试已成为软件测试的主要方面之一。它已经普及,因为它能够测试...
关键字:
实时测试
软件开发
验证是检查软件是否符合其规格的过程。它回答了以下问题:“我们是否正确构建了产品?”这意味着根据项目开始时定义的要求检查软件是否按预期运行。验证通常通过静态测试完成,这意味着软件实际上并未执行。相反,代码经过审查、检查或遍...
关键字:
软件开发
软件验证
嵌入式软件开发是一门应用广泛且不断发展的技术领域,为了满足不同应用场景的需求,开发人员可以采用多种架构方法。
关键字:
嵌入式
时间片
软件开发
事实表明,AI无法替代开发者,但更适用于优秀的开发者。而识别大型语言模型(LLM)生成的代码什么时候会出错,需要开发人员具有丰富的知识和经验。
关键字:
AI编程
软件开发
AI
大型语言模型
LLM
嵌入式开发是当今信息技术领域不可或缺的一部分,它融合了硬件设计、软件开发和系统集成等多个学科,专门用于创建那些被嵌入到特定设备或系统中的专用计算机系统。嵌入式开发的主要过程包括利用分立元件或集成器件进行电路设计、结构设计...
关键字:
嵌入式开发
硬件设计
软件开发
12月15日,一场以技术交流和创新碰撞为核心的开源大赛——开放原子开源大赛创新赛(简称“OpenHarmony创新赛”)在无锡市圆满落幕。
关键字:
软件开发