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层面,它看到的是不一样的东西。[捂脸]

上一篇下一篇

猜你喜欢

热点阅读