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 :

arithmétique de pointeurs voids ? ça marche mais g++ m'insulte!


Sujet :

C++

  1. #1
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Avril 2013
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2013
    Messages : 2
    Points : 2
    Points
    2
    Par défaut arithmétique de pointeurs voids ? ça marche mais g++ m'insulte!
    Bonjour!

    Après avoir relu les tutoriels du site, je n'ai pas trouvé de réponse. J'espère cependant ne pas poser une question idiote :p.

    J'essaye de travailler sur une structure déclarée et définie dans une librairie dynamique (.so) par offset et pointeurs dans le programme "appelant", ce qui m'amène à un warning de g++. Le code est fonctionnel, mais pourriez vous m'indiquer une méthode équivalente qui ne fasse pas crier g++?

    Ce que je fais est équivalent à:

    la structure (.h):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    typedef struct
    {
        float a;
        float b;
    }dumbStruct;
    le bout de code (.cpp)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
        void * ptr;
        dumbStruct Struc;
        Struc.a = 1;
        Struc.b = 2;
     
        ptr = &Struc;
        cout << "a :" << *(float*)ptr << "\n";
        cout << "b :" << *(float*)(ptr + sizeof(float)) << "\n\n";
    Sortie:
    a :1
    b :2
    La sortie est donc bonne, mais j'ai un warning de la forme:
    attention : pointer of type ‘void *’ used in arithmetic [-Wpointer-arith]
    Ok, donc il n'aime pas qu'on fasse de l'arithmétique avec un void *.....

    Les casts sont simplement pour provoquer le warning (je pourrais ici juste déclarer le pointeur en float, ou enlever les parenthèses du cast, mais ça ne traduirait pas mon vrai soucis de ne pas connaitre le type du pointeur). En réalité, je dispose uniquement d'un pointeur void sur la structure, et d'un vector de strings contenant le type de toutes les variables (je peut donc gérer les offsets avec sizeof() qui accepte des strings en entrée). Je ne peut pas déclarer ou caster le pointeur dans le bon type pour éviter de travailler sur un void (enfin pas à ma maigre connaissance).


    Pourriez-vous me proposer une alternative "propre" s'il vous plait? ( et donc qui ne fait pas pleurer gcc?)

    Un grand merci d'avance!

  2. #2
    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
    Ah oui, le coup des pointeurs void. Le standard ne supporte pas ça (mais à mon opinion, devrait), gcc le supporte en tant qu'extension GNU...

    Personnellement, je contourne le problème avec une fonction:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void* addoffset(void* pv, ptrdiff_t o)
    {
    	char * pby = pv;
    	return pby + o;
    }
     
    void const * addoffsetC(void const * pv, ptrdiff_t o)
    {
    	char const * pby = pv;
    	return pby + o;
    }
    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.

  3. #3
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Salut,
    tu peux garder le void*, mais pour éviter le warning il suffit de le caster en char* avant manipulation.
    Ou directement en float* puisque tu le connais.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    void * ptr;
        dumbStruct Struc;
        Struc.a = 1;
        Struc.b = 2;
     
        ptr = &Struc;
        // tout ce qui passe au-dessus n'est pas notre problème, on récupère un void*, on sait qu'il contient un dumbStruct donc on connait le contenu
        float* pF = reinterpret_cast<float*>(ptr);
        cout << "a :" << *pF << "\n";
        cout << "b :" << *(pF+1) << "\n\n";
        // il est encore plus simple de le caster directement dans notre structure
        dumbStruct* pStruct = reinterpret_cast<dumbStruct*>(ptr);
        cout<<"a : "<<pStruct->a<<endl<<"b : "<< pStruct->b<<endl<<endl;
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

  4. #4
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 614
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 614
    Points : 30 626
    Points
    30 626
    Par défaut
    Salut,

    Le fait est que void est, normalement, le type utilisé pour présenter:
    1. soit quelque chose d'inexistante( void foo() indique qu'il n'y a rien à renvoyer)
    2. soit quelque chose de totalement indéfini lorsqu'il est utilisé comme pointeur (c'est un pointeur sur "quelque chose dont on ignore tout").

    Un pointeur, ce n'est jamais qu'une adresse mémoire, et il n'y a strictement rien qui ressemble plus à une adresse mémoire... qu'une autre adresse mémoire, quel que soit le type de l'objet que l'on y retrouve

    Si l'on connait la taille d'un objet se trouvant à une adresse particulière, on peut donc demander au compilateur d'aller voir ce qui se trouve à l'adresse mémoire utilisée par "ce qui suit" l'objet se trouvant à notre adresse particulière, mais cela reste, malgré tout, assez dangereux dans le sens où ce n'est pas parce que l'on sait ce qui se trouve à l'adresse A que l'on sait forcément ce qui se trouve à l'adresse A + (taille de l'objet se trouvant à l'adresse A).

    L'avertissement que tu obtiens t'incite donc tout simplement à te méfier de l'arithmétique des pointeurs parce que tu effectue un transtypage "brutal" de ce qui se à une adresse calculée, et que le compilateur "est obligé" de te faire confiance, sans aucun moyen de vérifier que ce que tu lui dit ("l'adresse ptr+ taille d'un float doit être considérée comme l'adresse d'un float") est effectivement correct.

    L'idéal est donc d'abandonner ton void* "aussi vite que possible" au profit d'un pointeur sur la structure effectivement utilisée, et de préférer par la suite accéder "simplement" aux éléments de cette structure par les noms qui en représentent les différents champs
    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

  5. #5
    Candidat au Club
    Homme Profil pro
    Inscrit en
    Avril 2013
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2013
    Messages : 2
    Points : 2
    Points
    2
    Par défaut
    merci pour vos réponses! Et pour avoir pris le temps d'expliquer

    C'est maintenant clair, je vais tenir compte de tout ça!

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

Discussions similaires

  1. Ordinateur marche mais ecran eteint
    Par bourvil dans le forum Périphériques
    Réponses: 18
    Dernier message: 19/12/2005, 09h02
  2. Code qui marche, mais pas la mise à jour
    Par Cablan dans le forum Access
    Réponses: 7
    Dernier message: 24/10/2005, 17h09
  3. Script qui marche mais pas elegant[newbie]
    Par billybob2006 dans le forum Langage
    Réponses: 4
    Dernier message: 21/10/2005, 12h25
  4. [PL/SQL] requete qui marche mais pas dans un cursor
    Par victor.ward dans le forum Langage SQL
    Réponses: 3
    Dernier message: 09/09/2005, 22h21
  5. [Servlet - MySQL] Ca marche mais message d'erreur quand même
    Par ShinJava dans le forum Servlets/JSP
    Réponses: 2
    Dernier message: 09/11/2004, 15h15

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