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

StackOverflow https://stackoverflow.com/questions/1610875

Вопрос

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

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

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

Использование <=> в транке LLVM

Это было полезно?

Решение

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

С другой стороны, нет ничего плохого в использовании goto, когда это лучший инструмент для работы. Если его использование оправдано и является самым чистым способом решения проблемы, то это всегда правильно, независимо от & Quot; общего высказывания & Quot;.

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

Другие советы

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

Я только очень быстро взглянул на реализацию 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, поэтому, пожалуйста, дайте мне знать, если я не понял код!

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top