名字修饰(Demangling)的映射逻辑是什么?为何size_t对应'm'?
为什么size_t的typeid.name()输出'm'?
首先得明确:typeid().name()的输出是编译器特定的名字修饰简写,C++标准没规定具体格式,GCC用的是一套自己内部的简写规则。
核心原因:size_t是unsigned long的别名
size_t本身不是新类型,是标准库通过typedef定义的无符号整数别名,具体对应哪个基础类型取决于系统架构:
- 在64位系统上,
size_t几乎都是unsigned long的别名 - 在32位系统上,可能是
unsigned int的别名
而GCC的名字修饰规则里,unsigned long的简写就是**'m'**,所以当size_t映射到unsigned long时,typeid(i).name()就会输出'm'。
GCC的基础类型简写规则(常见部分)
给你列几个常用的对应关系,方便理解:
i→intj→unsigned intl→longm→unsigned longx→long longy→unsigned long long
验证解修饰后的完整类型
如果想确认'm'对应的真实类型,可以用GCC提供的__cxa_demangle函数解修饰,代码示例:
#include <typeinfo> #include <iostream> #include <cxxabi.h> int main() { size_t i = 5; const char* mangled = typeid(i).name(); int status; char* demangled = abi::__cxa_demangle(mangled, nullptr, nullptr, &status); if (status == 0) { std::cout << "原简写:" << mangled << "\n解修饰后:" << demangled << '\n'; free(demangled); } return 0; }
运行后会输出类似:
原简写:m 解修饰后:unsigned long
这就直接验证了'm'对应的真实类型。
注意事项
不同编译器的修饰规则完全不一样,比如MSVC的typeid(size_t).name()会直接输出unsigned int或unsigned long的完整字符串,不会用'm'这种简写。所以这类输出只能作为编译器特定的调试信息,不能写进跨平台的业务代码里。
内容的提问来源于stack exchange,提问作者mascai
相关产品推荐
相关产品推荐

