Что такое "пониженные vtable ссылки"? - PullRequest
2 голосов
/ 03 августа 2011

Диагностическая пропаганда Кланга содержит этот отрывок:

Поскольку у Clang есть подсветка диапазона, ему никогда не нужно печатать свой код обратно вам. Это особенно плохо в G ++ (который часто выдает ошибок, содержащих пониженные ссылки vtable ), но даже GCC может выдавать непостижимые сообщения об ошибках в некоторых случаях, когда он пытается это сделать.

Поиск в этой фразе не очень полезен, и последующий пример совершенно не связан.

Может кто-нибудь опубликовать пример того, о чем идет речь?

Спасибо.

1 Ответ

5 голосов
/ 03 августа 2011

Вот пример:

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 ++ деревья абстрактного синтаксиса (AST) для различных операций C ++, анализатор просто сразу понижает их до их эквивалента в C. В этом случае GCC синтезирует структуру, содержащую vtable, и разыменование указателя на bar затем уменьшается до серии разыменований указателя C, приведений, арифметики указателя и т. Д.

Clang не имеет этой проблемы, потому что он имеет очень чистый AST, который непосредственно представляет исходный код. Если вы измените пример на:

struct a {
  virtual int bar();
};

struct foo : public virtual a {
};

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

.. чтобы код был действительным, затем попросите clang сбросить его ast с помощью clang -cc1 -ast-dump t.cc, вы получите:

...
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 *'))))))

-Крис

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...