2009-10-23 5 views
6

LLVM dispose de sa propre alternative à la RTTI qui est une amélioration de la vitesse par rapport à la RTTI intégrée et qui permet la conversion dynamique en classes sans vtable (dyn_cast). Cependant, il peut toujours être utilisé exactement de la même façon que dynamic_cast<>, bien qu'il puisse être utilisé avec plus de classes.Est-ce que LLVM est une exception à la règle pour éviter les lancements dynamiques?

projet

dyn_cast<> template documentation

LLVM est une bonne réputation C++ si cela semble voler dans le visage de la commune disant que trop de moulages dynamiques est un signe de mauvaise conception, aussi connu comme une odeur de code. Sûrement un casting dynamique plus performant ne fait rien pour améliorer son utilisation dans la conception qu'un standard dynamic_cast. Alors, qui est ici? Y a-t-il des cas où l'utilisation à grande échelle de la coulée dynamique est un bon choix de conception dans le code C++? Google affiche 690 occurrences de ce type de diffusion dynamique dans le code source du LLVM.

Uses of dyn_cast<> in LLVM trunk

+0

Je pense que cela montre simplement que "parfois, dans un grand projet de logiciel, vous devez contourner certaines des règles". Ou peut-être que «les compilateurs, ou les frameworks liés au compilateur, doivent se contorsionner avec une supercherie de bas niveau, ce qui est généralement une mauvaise idée». Cela ne signifie pas que nous pouvons conclure quoi que ce soit à propos de l'utilisation de 'dynamic_cast' * en général. * – jalf

+0

Cela semble ignorer purement et simplement" les règles ". Je n'appellerais pas 690 occurrences en flexion des règles.Je ne vois rien de spécial au sujet des compilateurs ou des frameworks liés au compilateur qui signifient qu'ils sont autorisés à briser les croyances de conception. La conversion dynamique ici n'a aucun effet sur le code de sortie ou le code d'entrée du compilateur, cela fait simplement partie de la conception. Je pourrais continuer votre argumentation en disant que tout logiciel suffisamment volumineux ou complexe est autorisé à bafouer les règles de conception, ce qui remet sérieusement en question ce type de conseil de conception pour éviter 'dynamic_cast'. –

Répondre

7

Alors que les hits de performance sont une raison pour éviter dynamic_cast<> pour les hiérarchies de grande classe, ce n'est pas la seule raison pour laquelle vous pourriez vouloir les éviter. Plus performant ou non, il ne devrait pas être plus encouragé à utiliser dyn_cast<> à cause de cette affirmation. Par contre, il n'y a absolument rien de mal à utiliser dynamic_cast<> quand c'est le meilleur outil pour le travail. Si son utilisation est justifiée, et la façon la plus propre de résoudre un problème, alors c'est toujours juste, indépendamment du "dicton commun".

Je ne voudrais certainement pas éviter les projets populaires simplement parce qu'ils utilisent dynamic_cast<> s, goto s ou tout autre idiome qui est tombé en disgrâce.

+0

Absolument, je pense que c'est un projet génial, cela signifie-t-il que nous devrions prendre moins de précautions pour ne pas avoir 'dynamic_cast <>'? –

+0

non, vous devriez garder le conseil à l'esprit lorsque vous les utilisez et pensez, "est-ce la meilleure façon de le faire?" –

1

Je pense que la dynamique des moulages sont mauvais non pas parce qu'ils sont lents, mais parce qu'ils impliquent que votre code est trop étroitement couplé.

+0

Ils sont très lents aussi, cependant. Environ 1 microsec une pop pour nous. – Crashworks

+0

@Crashworks - Quelle est la profondeur de la hiérarchie d'héritage? Je crois que l'implémentation de 'dynamic_cast' par GCC est O (n) dans la profondeur, ce qui peut être très mauvais pour certains systèmes. – Tom

+0

Je pense que c'est environ 6-8 niveaux dans le cas que j'ai testé. Il y a littéralement des milliers de classes dans toute l'application. – Crashworks

-1

J'ai seulement jeté un rapide coup d'œil sur l'implémentation de dyn_cast et isa dans la documentation LLVM.

Le exmaple dans le code les éléments suivants sont:

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; 
} 

Le test est appelé avec un B et a:

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

Si je comprends ce qui se passe correctement, le modèle isa (qui est utilisé par dyn_cast) utilise la spécialisation explicite de isa_impl pour lier la barre avec foo. Dans les exemples donnés, il semble que isa<foo>(B1) retourne vrai!

Quoi qu'il en soit, c'est un comportement très différent de celui de dynamic_cast, donc je ne pense vraiment pas que vous pouvez les comparer les uns aux autres.

De toute évidence, je peux mal comprendre ce que fait LLVM, alors s'il vous plaît faites le moi savoir si je n'ai pas compris le code!

+0

Directement à partir de la documentation: L'opérateur dyn_cast <> est une opération de "vérification de la distribution". Il vérifie si l'opérande est du type spécifié, et si c'est le cas, lui renvoie un pointeur (cet opérateur ne fonctionne pas avec les références). Si l'opérande n'est pas du bon type, un pointeur nul est retourné. Ainsi, cela fonctionne très bien comme l'opérateur dynamic_cast <> en C++, et devrait être utilisé dans les mêmes circonstances. Donc, je ne vois pas pourquoi vous ne pouvez pas comparer dynamic_cast contre dyn_cast. Dans votre exemple, je ne vois pas d'où viennent les B1 et B2. –

+0

Le code ci-dessus provient d'un lien sur la page mentionnée dans la question. C'est leur code (c'est-à-dire LLVM). Voici le lien direct: http://llvm.org/doxygen/Casting_8h-source.html. B1 et B2 proviennent d'un exemple sur cette page plus bas. Je viens de couper et coller le code de leur en-tête. BTW, rien de ce que vous avez collé ici dit réellement comment la distribution dynamique a lieu. Il dit simplement que c'est un "casting" similaire à dynamic_cast. –

+1

Je ne pense pas que la mise en œuvre affecte vraiment la question que je pose ici. La citation clé de la documentation verbatim est la suivante: «Ainsi, cela fonctionne très bien comme l'opérateur dynamic_cast <> en C++, et devrait être utilisé dans les mêmes circonstances. –

Questions connexes