2019-06-14 Struct和Class的区别
2019-06-14 本文已影响0人
memset
参考资料:
安腾C++ABI文档(gcc/clang):https://itanium-cxx-abi.github.io/cxx-abi/
安腾C++ABI代码:https://github.com/microsoft/clang/blob/master/lib/AST/Mangle.cpp
微软C++ABI文档(非官方):https://en.wikiversity.org/wiki/Visual_C%2B%2B_name_mangling
微软C++ABI代码:https://github.com/microsoft/clang/blob/master/lib/AST/MicrosoftMangle.cpp
Wiki简介:https://en.wikipedia.org/wiki/Name_mangling
差NameMangling的补完。
现象:明明实现了一个函数但是,被linker告知找不到函数。函数的参数使用了(A* foo),其中A是一个前置声明的Class或者Struct。前置声明是,A的类型是struct,但是定义时A是class。A的真实身份是class,但是函数以为它需要一个struct指针的参数。网上关于C++中Class和Struct的论述都是,除了可见性(public、private)之外,其它都是是一样的。但对于微软来说,这XX就是在扯淡。
gcc/clang是这么翻译class和struct的:
<class-enum-type> ::= <name> # non-dependent type name, dependent type name, or dependent typename-specifier
::= Ts <name> # dependent elaborated type specifier using 'struct' or 'class'
::= Tu <name> # dependent elaborated type specifier using 'union'
::= Te <name> # dependent elaborated type specifier using 'enum'
不管是struct还是class,都是用Ts来标识。
但是msvc是这么翻译class和struct的:
void MicrosoftCXXNameMangler::mangleTagTypeKind(TagTypeKind TTK) {
switch (TTK) {
case TTK_Union:
Out << 'T';
break;
case TTK_Struct:
case TTK_Interface:
Out << 'U';
break;
case TTK_Class:
Out << 'V';
break;
case TTK_Enum:
Out << "W4";
break;
}
}
struct和class分别用不同的字母来标记。
在Linker层面,它看到的是不一样的东西。[捂脸]