Является ли LLVM исключением из правила для избежания динамического приведения? - PullRequest
6 голосов
/ 23 октября 2009

LLVM имеет собственную альтернативу RTTI, созданную вручную, которая является улучшением скорости по сравнению со встроенным RTTI и позволяет выполнять динамическое приведение к классам без vtable (dyn_cast). Тем не менее, он все еще может использоваться точно так же, как dynamic_cast<>, хотя он позволяет использовать его с большим количеством классов.

dyn_cast<> шаблон документации

LLVM - это авторитетный проект C ++, так что, похоже, это противоречит распространенному утверждению, что слишком много динамических приведений является признаком плохого дизайна, также известного как запах кода. Несомненно, более динамичное приведение в действие ничего не делает для улучшения его использования в дизайне, чем стандартное dynamic_cast. Так кто здесь? Существуют ли случаи, когда широкомасштабное использование динамического приведения является хорошим выбором при разработке кода C ++? Google обнаруживает 690 случаев такого рода динамического приведения в исходном коде транка LLVM.

Использование dyn_cast<> в магистрали LLVM

Ответы [ 3 ]

7 голосов
/ 24 октября 2009

Хотя снижение производительности является причиной, по которой следует избегать dynamic_cast<> для больших иерархий классов, это не единственная причина, по которой вы можете их избежать. Лучше выступать или нет, не стоит больше поощрять использовать dyn_cast<> из-за этой претензии.

С другой стороны, нет ничего плохого в использовании dynamic_cast<>, когда это лучший инструмент для работы. Если его использование оправдано и является самым чистым способом решения проблемы, то это всегда правильно, независимо от «общего высказывания».

Я бы, конечно, не стал избегать популярных проектов просто потому, что они используют dynamic_cast<> s, goto s или любую другую идиому, которая потеряла популярность.

1 голос
/ 23 октября 2009

Я думаю, что динамические броски плохи не потому, что они медленные, а потому, что они подразумевают, что ваш код слишком тесно связан.

0 голосов
/ 23 октября 2009

Я только очень быстро взглянул на реализацию dyn_cast и isa в документации LLVM.

Пример в коде имеет следующее:

struct bar {
  bar() {}
private:
  bar(const bar &);

};
struct foo {
  void ext() const;
  /*  static bool classof(const bar *X) {
    cerr << "Classof: " << X << "\n";
    return true;
    }*/
};

template <> inline bool isa_impl<foo,bar>(const bar &Val) {
  errs() << "Classof: " << &Val << "\n";
  return true;
}

Тест вызывается с B и имеет:

if (!isa<foo>(B1)) return;
if (!isa<foo>(B2)) return;

Если я правильно понимаю, что происходит, шаблон isa (который используется dyn_cast) использует явную специализацию isa_impl, чтобы связать панель с foo. В приведенных примерах кажется, что isa<foo>(B1) возвращает true!

Во всяком случае, это поведение очень отличается от поведения dynamic_cast, поэтому я действительно не думаю, что вы можете сравнить их друг с другом.

Очевидно, что я неправильно понимаю, что делает LLVM, поэтому, пожалуйста, дайте мне знать, если я не понял код!

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