2011-08-03 6 views
2

クラン自身diagnostics propagandaは、この抜粋が含まれています「下げられたvtable参照」とは何ですか?

クランは、範囲のハイライトを持っているので、それはかなりあなたに戻ってあなたのコードを印刷する必要はありません。これは、G ++(特に、の下位ビットを含むのエラーを出力する)では悪いですが、GCCでさえ、これを試みるときに紛らわしいエラーメッセージを生成することがあります。

このフレーズをグーグルで検索しても何も役に立ちません。後の例は完全に無関係です。

誰かが話していることの例を投稿できますか?

ありがとうございました。ここ

答えて

5

は一例であり:

struct a { 
    virtual int bar(); 
}; 

struct foo : public virtual a { 
}; 

void test(foo *P) { 
    return P->bar()+*P; 
} 

クランが生成:

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' 

そのC++フロントエンドは、上部にボルト止めされているため、GCCは、これを行います多くの場合、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(); 
} 

..コードが有効であるように、その後、「打ち鳴らす-cc1 -astダンプ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 *')))))) 

-Chris

+0

わかりました、これまで私はこれを見たことがありません。 ' .a :: _ vptr $ a'が何であるかを説明できるなら、ケーキを持っていなければなりません。 (私はvtableが何であるかを知っている。ちょうどそのエキゾチックな文字列を作り出したものではない。[仮想継承]と関係するもの(http://www.codeproject.com/KB/cpp/FastDelegate.aspx) ) – spraff

関連する問題