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++

  1. #1
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    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.
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 366
    Points : 440
    Points
    440
    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 averti
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    366
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 366
    Points : 440
    Points
    440
    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é
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    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.
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    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 averti
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    366
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 366
    Points : 440
    Points
    440
    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 sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    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 averti
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    366
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 366
    Points : 440
    Points
    440
    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 */
      }
    }

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    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.

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 366
    Points : 440
    Points
    440
    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)

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 366
    Points : 440
    Points
    440
    Par défaut
    Citation Envoyé par Médinoc
    Pas de map : C'est complètement exagéré et non-nécessaire.
    C est certes peut etre un peu exagere, mais si comme ca a l air d etre le cas, le unsigned long ne peut pas contenir de pointeur de maniere sure et maitrisee alors c est peut etre une proposition a consideree

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 366
    Points : 440
    Points
    440
    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

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Citation Envoyé par smashy
    (d ailleurs si le compilateur indique que la taille n est pas suffisante alors ... ben elle n est pas sense etre suffisante)
    Perdu. Ce warning indique qu'elle ne serait pas suffisante sur une plate-forme 64 bits. Donc, soit l'API utilisée accepte un ULONG_PTR comme paramètre de callback, soit elle-même n'est pas compatible 64 bits et ce n'est alors pas la peine d'aller plus loin dans cette direction.

    Note: Le SDK de Windows définit le type ULONG_PTR ainsi:
    • typedef __w64 unsigned long ULONG_PTR; sur une plate-forme 32 bits.
    • typedef unsigned __int64 ULONG_PTR; sur une plate-forme 64 bits.

    Sachant que le préfixe __w64 signifie "ce type fait 32 bits sur une plate-forme 32 bits, mais fera 64 bits sur une plate-forme 64 bits. Les types comme intptr_t et size_t possède ce préfixe, et les pointeurs font comme s'ils l'avaient.
    Résultat, on obtient un warning de portabilité 64 bits si l'on tente d'affecter un type "avec __w64" (ou un pointeur) à un type "sans __w64", sans cast explicite pour la taille.
    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.

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 366
    Points : 440
    Points
    440
    Par défaut
    Citation Envoyé par Médinoc
    . Ce warning indique qu'elle ne serait pas suffisante sur une plate-forme 64 bits.
    Perso, avec un tel warning j'aurais pas ete capable de decrypter par "attention ne marchera pas sur 64 bits !".

    J'aurai decrypte comme "attention , pas sense marche sur la plate-forme courante"

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    C'est pour cela que ces warnings disparaissent si l'on supprime l'option "warnings de portabilité 64 bits" (/wp64) dans un projet VS 2005.
    • La méthode "soigner la maladie à la source" pour virer le warning, c'est de remplacer les unsigned long concernés par des ULONG_PTR.
    • La méthode "prend cette aspirine et on verra plus tard", c'est de supprimer l'option /wp64 du projet.
    • La méthode "casser le thermomètre" pour le virer, c'est de static_caster en ULONG_PTR avant de reinterpret_caster en pointeur.

    (méthodes classées de la meilleure à la pire).
    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.

  16. #16
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Okay!! Merci Médinoc
    Je n'avais pas compris que c'était un warning dû à la portabilité sur 64bits. Du coup, j'ai supprimé l'option de compilation (detect 64 bits portalibity issues) et je n'ai plus mon warning.
    De toutes façon, l'API en question c'est twain_32, et comme son nom l'indique... elle n'est pas portable sur 64 bits. :p
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

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

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

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    Si tu as posté avant que j'édite mon dernier post, tu as donc choisi la solution "aspirine". Ce n'est pas la pire, et dans ton cas, c'est celle que j'aurais conseillée.
    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.

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 366
    Points : 440
    Points
    440
    Par défaut
    Magistral ! Merci pour le cours

  19. #19
    Expert éminent

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Points : 7 618
    Points
    7 618
    Billets dans le blog
    3
    Par défaut
    Haaaa les joies de TWAIN
    Il n'existe pas de version 64 bits de TWAIN, et le TWAIN de base était du 16/32 bits. C'est quand même vachement vieux (et lent).

    Il y a nécessité à utiliser TWAIN ?
    Parceque sinon, WIA est un meilleur choix pour les plateformes actuelles, à mon avis...
    N'oubliez pas de cliquer sur mais aussi sur si un commentaire vous a été utile !
    Et surtout

  20. #20
    r0d
    r0d est déconnecté
    Expert éminent

    Homme Profil pro
    tech lead c++ linux
    Inscrit en
    Août 2004
    Messages
    4 262
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : tech lead c++ linux

    Informations forums :
    Inscription : Août 2004
    Messages : 4 262
    Points : 6 680
    Points
    6 680
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par nicroman
    Il y a nécessité à utiliser TWAIN ?
    Non, je l'ai choisi parce que j'aime bien me prendre la tête pour rien

    Plus sérieusement, je n'ai pas le choix, je dois faire un pilote twain. Mais si j'ai un peu de temps, je vais jeter un coup d'oeil du côté de WIA lorsque mon driver fonctionnera. Quels sont les avantages à utiliser WIA?
    « L'effort par lequel toute chose tend à persévérer dans son être n'est rien de plus que l'essence actuelle de cette chose. »
    Spinoza — Éthique III, Proposition VII

+ 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