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

  1. #1
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur systèmes embarqués
    Inscrit en
    juin 2009
    Messages
    3 975
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur systèmes embarqués

    Informations forums :
    Inscription : juin 2009
    Messages : 3 975
    Points : 11 064
    Points
    11 064
    Billets dans le blog
    1

    Par défaut Adresse d'un void* vs un void*

    Bonjour,

    Je viens de faire les frais d'un code comme ceci :

    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
    #include <cstdio>
     
    struct Foo
    {
        int bar;
    };
     
    static Foo foo;
     
    void* getObject()
    {
        return &foo;
    }
     
    void useObject(void* object)
    {
        printf("%s %p\n", __PRETTY_FUNCTION__, object);
    }
     
    int main()
    {
        void* handle = getObject();
        useObject(handle);
        useObject(&handle);
    }
    En gros, passer un void* ou l'adresse d'un void*, le compilateur n'y voit pas de différence... Pas de warning, pas d'erreur quand on compile avec $ g++ prog.cc -Wall -Wextra -std=c++17 -pedantic (testable sur https://wandbox.org/).

    Comment ça se fait ?

    Merci d'avance !

  2. #2
    Rédacteur/Modérateur

    Homme Profil pro
    Network game programmer
    Inscrit en
    juin 2010
    Messages
    5 519
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : juin 2010
    Messages : 5 519
    Points : 24 047
    Points
    24 047

    Par défaut

    Vu que tout peut être cast vers et depuis void*, qu'il fasse un cast implicit de ton void** en void* est un moindre mal; le réel problème étant que tu manipules des void* entre les fonctions.
    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.

  3. #3
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    décembre 2015
    Messages
    818
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : décembre 2015
    Messages : 818
    Points : 4 243
    Points
    4 243

    Par défaut

    Bonjour,

    En efft, où vois-tu un problème? toute adresse est convertible implicitement en void*, d'ailleurs le type void* n'existe que pour cela. De la même manière, toute adresse d'une classe est convertible sans aucun warning en un pointeur sur sa base.
    Par contre la conversion inverse est refusée sans trans-typage (alors qu'en langage C, elle ne produit même pas un warning, ça c'est beaucoup plus gênant.)
    Et une idée pour ne pas avoir ce risque : ne pas utiliser le type void* que l'on devrait laisser au développements en C.

  4. #4
    Rédacteur/Modérateur

    Homme Profil pro
    Network game programmer
    Inscrit en
    juin 2010
    Messages
    5 519
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : juin 2010
    Messages : 5 519
    Points : 24 047
    Points
    24 047

    Par défaut

    Une astuce toute bête pour ne pas utiliser de void* directement, parce qu'en utiliser est inévitable avec les API C : une structure correctement nommée et maîtrisée qui l'englobe. Et c'est cette structure que tu manipules dans ton programme, en utilisant le void* interne uniquement en dernier recours quand tu appelles l'API qui le veut explicitement.
    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.

  5. #5
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur systèmes embarqués
    Inscrit en
    juin 2009
    Messages
    3 975
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur systèmes embarqués

    Informations forums :
    Inscription : juin 2009
    Messages : 3 975
    Points : 11 064
    Points
    11 064
    Billets dans le blog
    1

    Par défaut

    En fait j'écris des classes C++ pour wrapper les objets de mon RTOS écrit en C. Avec des joyeusetés comme des void* cachés derrière des typedefs et des fonctions qui prennent des fois des objets issus de ces typedefs, des fois des pointeurs...

    Du coup, c'est vrai, un void** est un pointeur sur void* et comme tout pointeur sur n'importe quoi il se convertit sans soucis en void*.... Une fois dit explicitement, c'est tellement évident.

    Merci !

  6. #6
    Rédacteur/Modérateur

    Homme Profil pro
    Network game programmer
    Inscrit en
    juin 2010
    Messages
    5 519
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : juin 2010
    Messages : 5 519
    Points : 24 047
    Points
    24 047

    Par défaut

    Alors le plus simple est de simplement proposer l'interface complète qui l'englobe et tu ne devrais avoir aucun passage de ton void* en paramètre nulle part puisque c'est un membre.
    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.

  7. #7
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur systèmes embarqués
    Inscrit en
    juin 2009
    Messages
    3 975
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur systèmes embarqués

    Informations forums :
    Inscription : juin 2009
    Messages : 3 975
    Points : 11 064
    Points
    11 064
    Billets dans le blog
    1

    Par défaut

    C'est exactement ce que je compte faire

    Je suis par exemple en train de faire la classe BinarySemaphore. Elle a un constructeur par défaut, take() et give() et en interne je manipule deux void* cahcés par des typedefs. Ni vu, ni connu... mais faut juste que j'arrive à faire fonctionner ça sans encombre

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

Discussions similaires

  1. Réponses: 12
    Dernier message: 24/05/2013, 09h53
  2. void function() et void function(void)
    Par Kel-T dans le forum C
    Réponses: 3
    Dernier message: 10/06/2012, 13h34
  3. Différence entre "((void *) 0)" et "(void *)0"
    Par skeleton18 dans le forum Débuter
    Réponses: 1
    Dernier message: 10/04/2012, 19h16
  4. Recuperation d'une adresse dans un tableau de *void
    Par stc074 dans le forum Débuter
    Réponses: 10
    Dernier message: 28/01/2012, 02h55
  5. [argument par adresse] void *
    Par ZaaN dans le forum C++/CLI
    Réponses: 4
    Dernier message: 21/02/2008, 13h57

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