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

使用-nostdlib实现C++异常时出现int类型信息未定义引用错误

C++迷你标准库异常实现中的typeinfo for int问题

问题背景

我在做一个迷你标准库替代项目,尝试实现基础异常机制,写了一段极简代码:

int memory[4];

void* __cxa_allocate_exception(long unsigned int thrown_size) throw()
{
    return memory;
}

void __cxa_free_exception(void * thrown_exception) throw()
{
    
}

void __cxa_throw(void* thrown_exception, void * tinfo, void (*dest)(void*))
{
    while(1){};
}

extern "C" void _start()
{
    throw 2;
}

用-nostdlib编译时,出现链接错误:

undefined reference to `typeinfo for int'

查看编译器生成的汇编代码,能看到这一行:

mov     esi, OFFSET FLAT:typeinfo for int

核心疑问

  1. typeinfo for int到底是什么?它不是带空格的常规函数/变量名,完全搞不懂它的本质。
  2. 尝试添加-nostdlib -frtti -static-libstdc++编译选项后还是报错,这是为什么?

一、typeinfo for int的本质

typeinfo for int是GCC下C++ RTTI(运行时类型信息)机制的产物——它是代表int类型的**std::type_info实例的链接符号名**。

编译器会为每个需要RTTI支持的类型生成一个std::type_info对象,用来存储类型的名称、哈希值等信息。GCC对这个对象的符号命名规则就是typeinfo for [类型名],这里的空格是符号名的合法组成部分,链接器会把它当作一个整体符号处理。

当你抛出int类型异常时,编译器需要把该类型的std::type_info指针作为第二个参数传给__cxa_throw函数(也就是汇编里通过esi寄存器传递的内容),所以会在代码里引用这个符号,而你的迷你库没实现它,就会报链接错误。

二、为什么加-static-libstdc++仍报错

-nostdlib选项的作用是完全禁用所有标准库的链接,包括libstdc++。即使你加了-static-libstdc++,-nostdlib的优先级更高,编译器不会主动链接libstdc++里的类型信息对象。

另外,libstdc++的typeinfo依赖完整的标准库初始化流程,而你自定义的_start函数没有做这些初始化工作,就算强行链接也会出现其他问题。

三、可行的解决思路

根据你的迷你标准库项目需求,有两个方向可选:

1. 禁用RTTI

编译时添加-fno-rtti选项,这样编译器不会生成任何与RTTI相关的代码,自然也不会引用typeinfo符号。缺点是后续无法使用dynamic_cast等依赖RTTI的功能。

2. 手动实现对应类型的typeinfo符号

GCC对typeinfo符号有固定的名称修饰规则,比如int对应的typeinfo符号实际是_ZTIi(可以用c++filt _ZTIi命令验证,输出就是typeinfo for int)。你可以自己定义一个极简的type_info结构,然后生成对应的符号:

// 极简模拟std::type_info的结构
struct type_info {
    const char* __name;
};

// 定义int对应的typeinfo符号
extern "C" const type_info _ZTIi __attribute__((visibility("default"))) = {"int"};

这样链接器就能找到需要的符号,解决报错问题。


内容的提问来源于stack exchange,提问作者Jade Marker

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 10:25:16