Je voulais vérifier que typeid est évalué à la compilation lorsqu'il est utilisé avec un nom de type (ie typeid (int), typeid (std :: string) ...). Pour ce faire, j'ai répété en boucle la comparaison de deux appels de type, et je l'ai compilé avec les optimisations activées, afin de voir si le compilateur a simplifié la boucle (en regardant le temps d'exécution qui est 1us quand il simplifie au lieu de 160ms quand ce n'est pas le cas).Est-ce que typeid de type name est toujours évalué à la compilation en C++?
Et j'obtiens des résultats étranges, parce que parfois le compilateur simplifie le code, et parfois il ne le fait pas. J'utilise g ++ (j'ai essayé différentes versions 4.x), et voici le programme:
#include <iostream>
#include <typeinfo>
#include <time.h>
class DisplayData {};
class RobotDisplay: public DisplayData {};
class SensorDisplay: public DisplayData {};
class RobotQt {};
class SensorQt {};
timespec tp1, tp2;
const int n = 1000000000;
int main()
{
int avg = 0;
clock_gettime(CLOCK_REALTIME, &tp1);
for(int i = 0; i < n; ++i)
{
// if (typeid(RobotQt) == typeid(RobotDisplay)) // (1) compile time
// if (typeid(SensorQt) == typeid(SensorDisplay)) // (2) compile time
if (typeid(RobotQt) == typeid(RobotDisplay) ||
typeid(SensorQt) == typeid(SensorDisplay)) // (3) not compile time ???!!!
avg++;
else
avg--;
}
clock_gettime(CLOCK_REALTIME, &tp2);
std::cout << "time (" << avg << "): " <<
(tp2.tv_sec-tp1.tv_sec)*1000000000+(tp2.tv_nsec-tp1.tv_nsec) <<
" ns" << std::endl;
}
Les conditions dans lesquelles ce problème apparaissent ne sont pas claires, mais:
- s'il n'y a pas d'héritage en cause, pas problème (toujours la compilation)
- si je fais une seule comparaison, aucun problème
- le problème n'apparaît qu'avec une disjonction des comparaisons si toutes les conditions sont fausses
donc, il y a quelque chose que je n'ai pas avec le fonctionnement de typeid (est-il toujours supposé être évalué lors de la compilation lorsqu'il est utilisé avec le type nam es?) ou peut-il s'agir d'un bug gcc en évaluation ou en optimisation? En ce qui concerne le contexte, j'ai localisé le problème dans cet exemple très simplifié, mais mon but est d'utiliser typeid avec les types de modèles (car la spécialisation du modèle de fonction partielle n'est pas possible).
Merci pour votre aide!
Est-ce que vous basez votre conclusion entièrement sur la durée de l'exécution de votre code, ou avez-vous une preuve plus définitive de ce que le compilateur produit réellement? –
Pouvez-vous concevoir votre programme sans avoir besoin de 'typeid'? Un programme qui compare les types d'objets est considéré comme un programme OO mal formé. –
Dennis> Oui, mais je viens de vérifier le code asm et je peux confirmer que dans un cas il y a 6 instructions sans saut entre les deux appels clock_gettime, et dans l'autre cas 15 instructions avec 2 sauts incluant une boucle évidente. – cyril42e