IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

déréférencement du pointeur type-punned brisera les strictes d'aliases


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    216
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2003
    Messages : 216
    Par défaut déréférencement du pointeur type-punned brisera les strictes d'aliases
    Bonjour,

    Voici un code que j'ai trouvé sur le net pour calculer rapidement la racine carré :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    inline float CMathFct::squareRoot(float number)
    {
    	long i;
    	float x, y;
    	const float f = 1.5F;
     
    	x = number * 0.5F;
    	y  = number;
    	i  = * ( long * ) &y; //warning ici
    	i  = 0x5f3759df - ( i >> 1 );
    	y  = * ( float * ) &i; //warning ici
    	y  = y * ( f - ( x * y * y ) );
    	y  = y * ( f - ( x * y * y ) );
    	return number * y;
    }
    Quand je compile ce code avec l'option -O2 de g++, tout se passe bien mais quand je compile avec l'option -O3, j'ai ce warning :
    "attention : déréférencement du pointeur type-punned brisera les strictes d'aliases"

    Comment faire pour ne plus l'avoir ? Merci

  2. #2
    Membre expérimenté Avatar de Kujara
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    262
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2006
    Messages : 262
    Par défaut
    Ca me parait extremement foireux comme code...

    Avant toute chose, pose toi la question de savoir si tu a reellement besoin de ça.

    Ensuite, met les messages d'erreur en anglais la prochaine fois, la traduction automatique c'est incomprehensible.

    Et finalement, les 2 warnings correspondent aux casts, que d'ailleurs je ne comprends pas, donc j'aurais tendance a les remettre en cast normal :

    i = static_cast<long>( y);

    Apres, si il touche directement a l'encodage des floats, c'est vraiment hyper pourri comme bout de code.


    Pour info, voici la racine carrée version speed, methode Ogre3D :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    // returns a for a * a = r
    float asm_sqrt( float r )
    {
    #if  OGRE_COMPILER == OGRE_COMPILER_MSVC &&  OGRE_ARCH_TYPE == OGRE_ARCHITECTURE_32
     
        __asm {
            fld r // r0 = r
            fsqrt // r0 = sqrtf( r0 )
        } // returns r0
     
    #else
     
    	return sqrt( r );
     
    #endif
    }
    Comme tu peux le voir sur les #define, la partie asm n'est valable que pour Windows.

    Si Ogre3D n'utilise pas de feinte sous gcc, c'est probablement parcequ'il n'y en a pas ou que ce n'est pas la peine ... ( ne sous estime pas l'implementation du sqrt de base).

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    216
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Avril 2003
    Messages : 216
    Par défaut
    Merci pour ta réponse

    Pour mon compilateur, je ne sais pas pourquoi il essaye de traduire certain message en français et d'autre non !

    Pour ce qui est du code pourri...c'est quand même JC qui l'a écrit (notre fameux John Carmack).
    Le static_cast ne fonctionne pas : le code compile mais à l'exécution, j'ai n'importe quoi comme résultat. Et le code de Ogre ne m'intéresse guère si ce n'est que pour Windows

    Une idée ?!

  4. #4
    Membre expérimenté Avatar de Kujara
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    262
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2006
    Messages : 262
    Par défaut
    Citation Envoyé par casafa Voir le message
    Pour ce qui est du code pourri...c'est quand même JC qui l'a écrit (notre fameux John Carmack).
    Ok, si c'est une approximation, ça explique pas mal de choses ^^.
    Notemment pourquoi j'ai rien compris, et pourquoi Ogre l'utilise pas.

    Le static_cast ne fonctionne pas : le code compile mais à l'exécution, j'ai n'importe quoi comme résultat. Et le code de Ogre ne m'intéresse guère si ce n'est que pour Windows

    Une idée ?!
    Vi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
    float SquareRootFloat(float number) {
        long *i;
        float x, y;
        const float f = 1.5F;
     
        x = number * 0.5F;
        y  = number;
        i  = reinterpret_cast<long*>( &y);
       * i  = 0x5f3759df - ( *i >> 1 );
        float * l_tempY  = reinterpret_cast<float *>(i) ;
        y = *l_tempY;
        y  = y * ( f - ( x * y * y ) );
        y  = y * ( f - ( x * y * y ) );
        return number * y;
    }
    Ca marche chez moi, et ça me sort pas de warning, et ça donne le bon resultat pour un sqrt ( 2 ).

    Par contre, savoir si c'est rellement plus rapide.... Le sqrt de base de Quake3 date d'y a quoi, 9 ans ? La version actuelle est probablement plus rapide.
    A tester ?

  5. #5
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Citation Envoyé par Kujara Voir le message
    <snip>

    Par contre, savoir si c'est rellement plus rapide.... Le sqrt de base de Quake3 date d'y a quoi, 9 ans ? La version actuelle est probablement plus rapide.
    A tester ?
    Pas forcément...

    Bien sur, tu verra une différence de temps entre le temps de calcul d'une racine carrée sur une machine de 9 ans et le temps de calcul d'une racine carrée sur une machine actuelle...

    Mais la différence sera uniquement due à la rapidité avec laquelle le processeur va effectuer les différentes instructions...

    On a très vite fait le tour des algorithmes possibles pour calculer la racine carrée d'un nombre (je ne suis même pas sur qu'il en existe beaucoup plus de deux)...

    Alors, *peut être* y a-t-il un algorithme plus efficace qu'un autre, et *peut-être* peut-on trouver une implémentation de cet algorithme qui fera encore gagner quelque fréquences d'horloge...

    Mais, l'un dans l'autre, il y a fort à parier que l'algorithme utilisé du temps de Quake 3 pour calculer la racine carrée soit encore exactement celui qui est utilisé actuellement... Et même que le code fourni ici soit... une implémentation "perso" de cet algorithme
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  6. #6
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 397
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 397
    Par défaut
    Kujara: Attention, ces deux expressions ont des valeurs totalements différentes:
    • static_cast< long >(unDouble) retourne la partie entière (J'oublie toujours quelles sont les règles d'arrondi dans ce cas-là, et dans ce post je m'en moque).
    • *reinterpret_cast< long const * >(&unDouble) donne la valeur servant à coder le flottant, valeur dépendant du type de codage. Pour des flottants IEEE, on peut prévoir à quoi ça correspond..
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  7. #7
    Membre expérimenté Avatar de Kujara
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    262
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Décembre 2006
    Messages : 262
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Kujara: Attention, ces deux expressions ont des valeurs totalements différentes:
    • static_cast< long >(unDouble) retourne la partie entière (J'oublie toujours quelles sont les règles d'arrondi dans ce cas-là, et dans ce post je m'en moque).
    • *reinterpret_cast< long const * >(&unDouble) donne la valeur servant à coder le flottant, valeur dépendant du type de codage. Pour des flottants IEEE, on peut prévoir à quoi ça correspond..
    Je sais, le static_cast etait une erreur de ma part ( j'avais pas compris le bout de code quand j'en ai parlé).

    Le reinterpret cast marche très bien et fait ce qu'on lui demande, c'est a dire interpreter la zone mémoire pointée comme etant d'un autre type.

    J'oublie toujours quelles sont les règles d'arrondi dans ce cas-là, et dans ce post je m'en moque
    Arrondi inferieur pour autant que je me souvienne.

  8. #8
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    L'avertissement te signale que la manière dont tu fais ta conversion est pour le moins dangeureuse:

    Voyons le raisonnement par étape pour essayer de te faire comprendre pourquoi le compilateur rechigne
    1. &y ==> demande l'adresse à laquelle se trouve y (un réel) (on va appeler le résultat A)
    2. (long*) A ==> signale que l'on veut considérer A comme l'adresse à laquelle se trouve un entier (appelons le résultat B)
    3. * B==> demande la valeur contenue à l'adresse B (appelons le résultat C)
    4. i= C assigne la valeur (de type long) de C à i

    On peut comprendre que ce genre de comportement soit de nature à éveiller les crainte du compilateur
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Êtes-vous pour ou contre les "strict type hints" ?
    Par RideKick dans le forum Langage
    Réponses: 44
    Dernier message: 21/03/2012, 21h18
  2. Réponses: 2
    Dernier message: 20/03/2011, 19h37
  3. Réponses: 3
    Dernier message: 12/01/2007, 10h25
  4. Réponses: 2
    Dernier message: 07/10/2004, 17h00
  5. Réponses: 2
    Dernier message: 30/08/2004, 14h48

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo