You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ARM GCC下禁用RTTI类型名存储且保留dynamic_cast的方法

结论

你所用的arm-none-eabi-g++ 10.3版本,没有官方提供的编译选项可以单独禁用RTTI中的类型名存储、同时保留原生dynamic_cast的完整功能,相关原因和可落地的优化方案如下:

原生RTTI无法单独裁剪类型名的核心原因

  • GCC的RTTI实现中,类型名存储不是和dynamic_cast逻辑解耦的独立可选模块:std::type_info及其派生的内部类(比如__class_type_info、__vmi_class_type_info)是dynamic_cast运行时转换逻辑的核心依赖,虽然转换过程的核心匹配逻辑不直接使用人可读的类型名字符串,但type_info结构的内存布局、符号生成规则和类型名字段是强绑定的,编译器没有开放单独移除该字段的配置开关。
  • 你观察到的空间占用,来自每个多态类型生成的typeinfo name for X符号,本质是mangled后的类型字符串,默认存在只读数据段。如果直接使用-fno-rtti选项,会彻底关闭整个RTTI机制,dynamic_cast会直接触发编译错误,无法满足需求。

可落地的优化方案

  • 优先用链接器自动裁剪未使用符号:编译阶段添加-fdata-sections -ffunction-sections选项,链接阶段添加-Wl,--gc-sections选项。只要你的工程中完全没有调用std::type_info::name()、没有使用typeid获取类型名相关的逻辑,链接器会自动回收所有没有被实际引用的类型名字符串,不会将其打包进最终二进制,这是零成本、无兼容性风险的优化手段。
  • 裁剪工具链RTTI实现(高成本方案):如果上述优化后空间仍不满足要求,且你能确认全工程没有任何逻辑访问类型名字段,可以修改GCC libstdc++源码中type_info相关结构的定义,移除存储类型名的指针字段,重新编译对应版本的arm-none-eabi工具链。但该方案维护成本极高,工具链升级时需要重新移植补丁,一旦存在遗漏的类型名访问逻辑会直接触发内存错误,量产项目不推荐使用。
  • 替换为嵌入式轻量RTTI实现:可以使用适配裸机场景的轻量RTTI库,这类实现仅保留dynamic_cast所需的继承关系元数据,完全不存储冗余的人可读类型名,空间占用比原生GCC RTTI低60%~80%,仅需要少量适配代码即可兼容现有dynamic_cast写法,是STM32等资源受限MCU场景的成熟方案。

注意:不要尝试使用二进制编辑工具暴力删除类型名对应的段内容,这类操作会破坏type_info结构的内存偏移,直接导致dynamic_cast运行时崩溃,且问题极难定位。

内容的提问来源于stack exchange,提问作者Patrick Wright

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 11:24:37