【问题标题】:What are "lowered vtable references"?什么是“降低的 vtable 引用”?
【发布时间】:2011-08-03 13:42:09
【问题描述】:

Clang 自己的 diagnostics propaganda 包含以下摘录:

由于 Clang 具有范围突出显示功能,因此它永远不需要将您的代码漂亮地打印回给您。这在 G++ 中尤其糟糕(通常会发出包含降低的 vtable 引用的错误),但即使 GCC 在某些情况下尝试这样做时也会产生难以理解的错误消息。

用谷歌搜索这个短语并没有什么帮助,后面的例子完全不相关。

有人可以发一个例子来说明它在说什么吗?

谢谢。

【问题讨论】:

    标签: gcc compiler-errors compiler-warnings clang vtable


    【解决方案1】:

    这是一个例子:

    struct a {
      virtual int bar();
    };
    
    struct foo : public virtual a {
    };
    
    void test(foo *P) {
      return P->bar()+*P;
    }
    

    Clang 产生:

    t.cc:9:18: error: invalid operands to binary expression ('int' and 'foo')
      return P->bar()+*P;
             ~~~~~~~~^~~
    

    GCC 4.2 产生:

    t.cc: In function ‘void test(foo*)’:
    t.cc:9: error: no match for ‘operator+’ in ‘(((a*)P) + (*(long int*)(P->foo::<anonymous>.a::_vptr$a + -0x00000000000000020)))->a::bar() + * P’
    t.cc:9: error: return-statement with a value, in function returning 'void'
    

    GCC 这样做是因为它的 C++ 前端在许多情况下都固定在 C 前端之上。解析器没有为各种 C++ 操作构建特定于 C++ 的抽象语法树 (AST),而是立即将它们降低到它们的 C 等价物。在这种情况下,GCC 会合成一个包含 vtable 的结构体,然后将对 bar 的指针解引用降低为一系列 C 指针解引用、强制转换、指针算术等。

    Clang 没有这个问题,因为它有一个非常干净的 AST,直接代表源代码。如果您将示例更改为:

    struct a {
      virtual int bar();
    };
    
    struct foo : public virtual a {
    };
    
    void test(foo *P) {
      P->bar();
    }
    

    .. 使代码有效,然后让 clang 用 "clang -cc1 -ast-dump t.cc" 转储它的 ast,你得到:

    ...
    void test(foo *P)
    (CompoundStmt 0x10683cae8 <t.cc:8:19, line:10:1>
      (CXXMemberCallExpr 0x10683ca78 <line:9:3, col:10> 'int'
        (MemberExpr 0x10683ca40 <col:3, col:6> '<bound member function type>' ->bar 0x10683bef0
          (ImplicitCastExpr 0x10683cac8 <col:3> 'struct a *' <UncheckedDerivedToBase (virtual a)>
            (ImplicitCastExpr 0x10683ca28 <col:3> 'struct foo *' <LValueToRValue>
              (DeclRefExpr 0x10683ca00 <col:3> 'struct foo *' lvalue ParmVar 0x10683c8a0 'P' 'struct foo *'))))))
    

    -克里斯

    【讨论】:

    • 哇,我以前从未见过这个。如果你能解释&lt;anonymous&gt;.a::_vptr$a 是什么,那你就有蛋糕了。 (顺便说一句,我知道 vtable 是什么,只是不知道是什么产生了那个奇异的字符串。我猜这与 virtual inheritence 有关。)
    猜你喜欢
    • 2011-01-14
    • 1970-01-01
    • 2011-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-04
    相关资源
    最近更新 更多