LLVM é uma exceção à regra para evitar moldes dinâmicos?
-
05-07-2019 - |
Pergunta
LLVM tem a sua própria mão rolou alternativa para RTTI que é uma melhoria de velocidade ao longo do built-in RTTI e permite fundição dinâmica às aulas sem vtable (dyn_cast
). No entanto, ele ainda pode ser usado exatamente da forma que dynamic_cast<>
é usado embora ele não permitir que ele seja usado com mais classes.
dyn_cast<>
template documentação
LLVM é um projeto respeitável C ++ pelo que esta parece voar em face do provérbio comum que muitos moldes dinâmicos é um sinal de design ruim, também conhecido como um cheiro de código. Certamente um elenco dinâmico melhor desempenho não faz nada para melhorar a sua utilização no projeto do que um dynamic_cast
padrão. Então, quem está aqui? Existem casos em que o uso em larga escala de fundição dinâmica é uma boa escolha projeto em código C ++? Google transforma-se 690 ocorrências deste tipo de fundição dinâmica no código fonte tronco LLVM.
Solução
Enquanto sucessos de desempenho são uma razão para evitar dynamic_cast<>
para grandes hierarquias de classe, não é a única razão que você pode querer evitá-los. Melhor desempenho ou não, não se deve ser mais incentivado a utilização dyn_cast<>
por causa desta afirmação.
Por outro lado, não há absolutamente nada de errado em usar dynamic_cast<>
quando é a melhor ferramenta para o trabalho. Se o seu uso é justificado, e a forma mais limpa para resolver um problema, então é sempre certo, independentemente do "ditado comum".
Eu certamente não orientar clara de projetos populares simplesmente porque eles usam dynamic_cast<>
s, goto
s ou qualquer outro idioma que está caído em desuso.
Outras dicas
Eu acho dinâmica moldes não são ruins porque eles são lentos, mas porque elas implicam que o código está muito intimamente ligado.
Eu só tenho tido um olhar muito rápido na implementação de dyn_cast e isa na documentação LLVM.
O exmaple no código tem o seguinte:
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;
}
O teste é chamado com um B
e tem:
if (!isa<foo>(B1)) return;
if (!isa<foo>(B2)) return;
Se eu entender o que está acontecendo corretamente, o modelo isa
(que é usado por dyn_cast
) utiliza o especialização explícita de isa_impl
a barra de links com foo. Nos exemplos dados, parece que isa<foo>(B1)
retornos verdade!
De qualquer forma, este é um comportamento muito diferente ao de dynamic_cast, então eu realmente não acho que você possa compará-los uns contra os outros.
Obviamente, eu posso ser mis-compreender o que LLVM está fazendo, então por favor deixe-me saber se eu não tenha entendido o código!