2009-11-30 23 views
9

Andrei Alexandrescu écrit dans Modern C++ Design:Quand typeid peut-il renvoyer différentes instances type_info pour le même type?

Les objets retournés par typeid ont stockage statique, de sorte que vous n'avez pas à vous soucier des problèmes à vie.

Andrei continue:

La norme ne garantit pas que chaque invocation, par exemple, typeid(int) renvoie une référence au même objet type_info.

Même si la norme ne le garantit pas, comment cela est-il implémenté dans les compilateurs courants, tels que GCC et Visual Studio?

En supposant que typeid ne fuit pas (et renvoie une nouvelle instance tous les appels), est-ce une "table" par application, par unité de traduction, par dll/so, ou quelque chose de complètement différent?

Y a-t-il des moments où &typeid(T) != &typeid(T)?

Je m'intéresse principalement aux compilateurs pour Windows, mais toute information sur Linux et sur d'autres plateformes est également appréciée.

+3

Une raison importante pour ce niveau de liberté était en effet la préoccupation pour les DLL. – MSalters

Répondre

10

Y at-il des moments où & typeid (T)! = & typeid (T)?

Je m'intéresse principalement aux compilateurs pour Windows, mais toute information sur Linux et sur d'autres plateformes est également appréciée.

Oui. Sous Windows, DLL ne peut pas avoir de symboles non résolus, donc. Si vous avez:

foo.h

struct foo { virtual ~foo() {} }; 

dll.cpp

#include "foo.h" 
... 
foo f; 
cout << &typeid(&f) << endl 

main.cpp

#include "foo.h" 
... 
foo f; 
cout << &typeid(&f) << endl 

Souhaitez-vous donner différentes indications.Parce qu'avant que dll était chargé, typeid (foo) devrait exister dans les dll et les exe primaires

Plus que cela, sous Linux, si l'exécutable principal n'était pas compilé avec -rdynamic (ou --export-dynamic), alors typeid serait résolu à différents symboles dans l'exécutable et dans l'objet partagé (ce qui n'arrive généralement pas sous les plates-formes ELF) en raison de certaines optimisations effectuées lors de la liaison exécutable - suppression des symboles inutiles.

1

Les standards laissent parfois un certain comportement non spécifié afin de donner une certaine liberté aux implémentations. Dans ce cas, la façon dont les TypeID sont gérés est laissée à l'implémentation du compilateur et on vous donne simplement un ensemble de règles (essentiellement: ne vous souciez pas de la façon dont la mémoire est allouée).

Existe-t-il une raison particulière pour laquelle vous devez pouvoir comparer des TypeIds en fonction de leur adresse mémoire? TypeIds remplacent déjà == et! = Afin de vous permettre de les comparer, et de fournir un nom() qui pourrait être utilisé pour les identifier de façon unique.

Si le langage de programmation C++ (Bjarne Stroustrup) est disponible, le chapitre 15 contient de nombreux détails sur la gestion des hiérarchies de classes. Peut-être que vous pourriez trouver une autre solution là-bas?

+3

Vous avez beaucoup de bons points, mais cela ne répond pas à ma question. Je n'ai pas besoin de comparer les adresses, je suis uniquement intéressé par la façon dont il est géré en interne dans les compilateurs. Mais ce qui m'intéresse le plus dans ce numéro, ce sont ceux de la conception de compilateur: comment et pourquoi il est implémenté de cette manière. Ajout d'étiquettes supplémentaires à la question. – dalle