链接时报“undefined reference to typeinfo”是因为启用了-fno-rtti,导致编译器不生成typeinfo符号,而代码或所链接的库仍依赖该RTTI信息;常见于混用RTTI开启/关闭的模块、虚函数未实现或第三方库RTTI配置不一致。

为什么链接时提示 undefined reference to `typeinfo`
这是 -fno-rtti 最典型的副作用:C++ 运行时类型信息(RTTI)被禁用后,dynamic_cast、typeid 无法使用,且所有依赖 RTTI 的符号(如 typeinfo、vtable 中的 typeinfo 指针)都不会生成。链接器找不到这些符号,就会报错。
常见触发场景包括:
- 项目中混用了启用 RTTI 的第三方库(比如 Boost、Qt 的某些模块),而你自己的代码加了
-fno-rtti - 调用了
dynamic_cast或typeid,但编译时没开 RTTI - 虚函数表里本该填入 typeinfo 指针的位置为空,导致运行时
dynamic_cast崩溃(即使侥幸通过链接)
什么情况下必须用 -fno-rtti
嵌入式或资源极度受限环境是主要使用场景。RTTI 会为每个含虚函数的类生成额外的 typeinfo 数据段,增大二进制体积,并可能增加启动时间与内存占用。
是否启用取决于实际约束:
- 裸机开发(无 OS)、MCU(如 Cortex-M 系列)常用
-fno-rtti -fno-exceptions组合 - Linux 用户态程序一般不需要关 RTTI;除非明确测量到 typeinfo 占用显著(>1% Flash / RAM)
- 若代码里完全不出现
dynamic_cast和typeid,且不链接依赖它们的库,关掉 RTTI 是安全的
-fno-rtti 和 -fno-exceptions 能否单独使用
可以单独使用,但组合更常见。两者影响不同机制:
-
-fno-rtti:仅移除类型识别信息,不影响异常抛出/捕获逻辑 -
-fno-exceptions:禁用throw/catch,同时隐式禁用栈展开(unwinding),也会删掉部分异常相关元数据 - 单独用
-fno-rtti而保留-fexceptions是合法的,但要注意:某些异常实现(如 libstdc++)在异常处理路径中可能间接依赖 typeinfo —— 实际中极少出问题,但非 100% 隔离
检查你的二进制是否真禁用了 RTTI
别只信编译参数。验证方法更可靠:
- 查符号:
nm -C your_binary | grep typeinfo,如果输出为空,说明 RTTI 已剥离 - 反汇编虚函数表:
objdump -d your_binary | grep -A2 "vtable for",观察第二项是否为0x0(即 typeinfo 指针空缺) - 写个最小测试用例,含
dynamic_cast,编译后运行看是否 segfault —— 这比文档更直接
注意:libstdc++ 或 libc++ 本身带 RTTI,静态链接时它仍会把 typeinfo 塞进来,除非你用 --static-libstdc++ 并确认目标库也编译自 -fno-rtti。这点最容易被忽略。


















