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 :

eviter un warning sur un cast


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 294
    Billets dans le blog
    2
    Par défaut eviter un warning sur un cast
    Bonjour à tous,

    dans le but de fournir un code le plus propre possible, je fais la chasse aux warnings. Et il y en a un que je ne sais pas comment supprimer.

    J'ai une fonction callback qui ressemble à cela:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void __stdcall MaCallback(  unsigned long context,  void* pData)
    {
    	MaClasse* pMonObjet = reinterpret_cast<MaClasse*>(context);
    	// ensuite je fais des traitements sur pMonObjet
    }
    Dans cette callback, je récupère le contexte. En fait, ce contexte est un pointeur sur une classe qui va être modifée dans cette callback.

    Voici le warning que j'obtiens (je travaille avec Visual8):
    warning C4312: 'reinterpret_cast' : conversion from 'unsigned long' to 'MaClasse *' of greater size
    Avez-vous une idée pour se débarrasser de ce warning?

    ps: je ne peux pas modifier la signature de ma callback, elle fait partie d'une sdk "externe" à mon projet.

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    366
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 366
    Par défaut
    question : avant de chasser le warning , est ce que ton code marche ?

    j'aurais tendance a dire que ton code converti un entier (que je suppose en 4 octets) vers un pointeur (que je suppose en 8 --> machine 64bits ?). Dans ce cas, la conversion telle qu elle semble carrement dangereuse (quand on utilise un context on devrait au pire donner un pointer et pas un entier de taille inconnu)

    Tu devrais verifier a affichant sur la sortie standard les sizeof( ... )

    tu peux aussi voir sizeof( long long) .

  3. #3
    Membre chevronné
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    366
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 366
    Par défaut
    derniere question : es tu sur que ce n est pas pData qu il faut caster ???

  4. #4
    r0d
    r0d est déconnecté
    Membre expérimenté

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    4 294
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 4 294
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par smashy
    question : avant de chasser le warning , est ce que ton code marche ?
    Oui ça fonctionne trés bien.

    Citation Envoyé par smashy
    j'aurais tendance a dire que ton code converti un entier (que je suppose en 4 octets) vers un pointeur (que je suppose en 8 --> machine 64bits ?). Dans ce cas, la conversion telle qu elle semble carrement dangereuse (quand on utilise un context on devrait au pire donner un pointer et pas un entier de taille inconnu)
    Oui mais ça je n'y suis pour rien: je ne peux pas modifier la signature de la callback et je ne vois pas d'autres moyen pour lui passer l'objet que je souhaite modifer.
    Citation Envoyé par smashy
    Tu devrais verifier a affichant sur la sortie standard les sizeof( ... )
    Il y a un problème de taille, j'ai bien compris, mais je sais pertinemment ce que je met dans ce paramètre 'context'; c'est d'ailleurs la raison pour laquelle j'utilise un reinterpret_cast.

    Citation Envoyé par smashy
    derniere question : es tu sur que ce n est pas pData qu il faut caster ???
    Oui.
    Le pData contient des données binaires trés spécifiques, et je n'ai aucun contrôle sur ce contenu.

  5. #5
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    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 395
    Par défaut
    Le pramètre context devrait sûrement être de type ULONG_PTR et non unsigned long.
    Ainsi, tu n'aurais pas ce warning de portabilité 64 bits.
    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.

  6. #6
    Membre chevronné
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    366
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 366
    Par défaut
    desole, mais je ne comprends alors pas du tout pourquoi le code ne plante meme pas

    Si j ai bien compris, tu enregistres a un moment la callback etn fournissant un pointer sur MaClasse . L api doit conserver ce pointer sous forme de unsigned long et appeler la callback avec ledit parametre (closure).

    Je ne comprends deja pas comment l information ne se perd pas au moment de l enregistrement ... alors au moment de l appel ...

    Si tu n as meme pas acces a pData , tu ne peux pas non plus faire une structure de pointeur ...

    reste la mechante donnee statique ( std::map<unsigned long,MaClass *> ) mais c est juste trashouille

  7. #7
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    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 395
    Par défaut
    smashy: Sur la plupart des plate-formes 32 bits, un long possède une taille suffisante pour contenir un pointeur.
    C'est ainsi qu'était utilisé SetWindowLong() sous Windows.

    Depuis, les plate-formes 64 bits commencent à se répandre, et cette garantie n'est plus valide. Alors, on utilise des types que l'implémenteur (voire même le standard) garantit comme étant de taille suffisante pour un pointeur: Ici, ULONG_PTR, ou bien sûr intptr_t qui fait désormais partie du standard C99...
    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.

  8. #8
    Membre chevronné
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    366
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 366
    Par défaut
    Citation Envoyé par Médinoc
    smashy: Sur la plupart des plate-formes 32 bits, un long possède une taille suffisante pour contenir un pointeur.
    Plupart : certes ... donc ca marche mais c est uniquement car c est la mode.
    (d ailleurs si le compilateur indique que la taille n est pas suffisante alors ... ben elle n est pas sense etre suffisante)

    On peux aussi imaginer que suite a des considerations d alignements memoire, la taille memoire utilisee par la fermeture, et par la mise sur la pile du context est suffisante pour contenir le pointeur mais bon ca ne resta pas tres secure de toute facon.

    Note: peu etre est il bon de faire un teste sur un debugger pour trouver les acces a la memoire non initialisee (equivalent de valgrind sous windows a priori)

  9. #9
    Membre chevronné
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    366
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 366
    Par défaut
    Citation Envoyé par Médinoc
    Ici, ULONG_PTR, ou bien sûr intptr_t qui fait désormais partie du standard C99...
    Certes, mais ...

    je ne peux pas modifier la signature de ma callback, elle fait partie d'une sdk "externe" à mon projet.
    ... donc il semble qu il faille de toute facon composer avec "unsigned long" et pas ULONG_PTR

  10. #10
    Membre chevronné
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    366
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 366
    Par défaut
    peut etre, modifier ma classe telle que
    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
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    class MaClass {
     
    static unsigned long count = 0;
     
    static map<unsigned long,MaClass *> mmm;
     
      int mykey;
     
      MaClass(){
     
        mykey = registerThis();
      }
     
      int registerThis(){
     
         mmm[count] = this;
     
        return count++;
      }
     
      static MaClass * getRegistered(unsigned long l){
     
        return mmm[l] ; /* attention cree une entree systematiquement don a approfondir */
      }
    }

  11. #11
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 395
    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 395
    Par défaut
    Pas de map : C'est complètement exagéré et non-nécessaire.
    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.

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

Discussions similaires

  1. Question sur les casts
    Par nicolas66 dans le forum C++
    Réponses: 3
    Dernier message: 16/03/2006, 19h03
  2. Warning sur un Alter Table
    Par Poussy-Puce dans le forum Langage SQL
    Réponses: 8
    Dernier message: 18/01/2006, 17h45
  3. [Dates] Warning sur filemtime()
    Par xave dans le forum Langage
    Réponses: 28
    Dernier message: 03/01/2006, 14h16
  4. Eviter les warnings "unused parameter"
    Par Le Furet dans le forum C
    Réponses: 9
    Dernier message: 03/10/2005, 22h29
  5. Réponses: 5
    Dernier message: 05/06/2004, 13h12

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