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 :

correction d'un calcul de pointeur pas très propre


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    613
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 613
    Par défaut correction d'un calcul de pointeur pas très propre
    Bonjour

    Soit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    typedef struct _mastruct {
    	/* ... */
    }mastruct;
     
    mastruct *pointeur;
    J'ai une source dans laquelle il était écrit ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    read ( fd, (void*)((long)pointeur) + sizeof(mastruct), taille)
    Et ça fonctionne bien, mais j'ai besoin de l'écrire plus proprement car ce n'est plus accepté par mon compilateur.
    Est ce que vous pensez que j'obtiendrai le même fonctionnement en faisant ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    read ( fd, (unsigned char *)((long)pointeur) + sizeof(mastruct), taille)
    merci

  2. #2
    Membre émérite
    Inscrit en
    Juillet 2005
    Messages
    512
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 512
    Par défaut
    Tout ces transtypages sont vraiement nécessaire ?

    De plus ajouter la taille de la structure à un pointeur je ne vois pas bien ce que cela peut donner, à part obtenir un pointeur qu va pointer je ne sais où ?

  3. #3
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    613
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 613
    Par défaut
    Je ne voulais pas trop rentrer dans le détail car ce n'est pas moi qui l'avait écrit, mais juste savoir si le fonctionnement sera identique.
    D'après ce que j'ai compris c'est pour pointer à la suite de la structure pour pouvoir lire des données (grace à un read) et les mettres à cet endroit là en mémoire.

    Cette expression est passé en deuxième paramètre du read (j'edite mon premier post en conséquence)

  4. #4
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par pasdeface Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    typedef struct _mastruct {
    	/* ... */
    }mastruct;
     
    mastruct *pointeur;
    J'ai une source dans laquelle il était écrit ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    read ( fd, (void*)((long)pointeur) + sizeof(mastruct), taille)
    Et ça fonctionne bien, mais j'ai besoin de l'écrire plus proprement car ce n'est plus accepté par mon compilateur.
    Est ce que vous pensez que j'obtiendrai le même fonctionnement en faisant ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    read ( fd, (unsigned char *)((long)pointeur) + sizeof(mastruct), taille)
    merci
    Et pourquoi pas
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    read(fd, pointeur+1, taille);
    et si reellement tu as une cible ou read n'a pas un void* comme second parametre (c'est quoi? la derniere mise a jour du systeme date de quand?)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    read(fd,(unsigned char*)(pointeur+1), taille);
    mais la lecture en binaire d'une struct, ca sent les problemes de portabilite a plein nez...

  5. #5
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    613
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 613
    Par défaut
    non, le problème n'est pas que read ne peut pas prendre de void *, il le peut.
    Le problème c'est l'opération + sur un void * qui n'est pas permise (et c'est logique) :
    error: pointer of type ‘void *’ used in arithmetic

  6. #6
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par pasdeface Voir le message
    non, le problème n'est pas que read ne peut pas prendre de void *, il le peut.
    Le problème c'est l'opération + sur un void * qui n'est pas permise (et c'est logique).
    Il n'y a donc pas de probleme avec ma premiere version?

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    613
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 613
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet Voir le message
    Il n'y a donc pas de probleme avec ma premiere version?
    Disons que ça compile, mais est ce que ça reviens vraiment au meme ?

  8. #8
    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
    Normalement, oui.
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    T * ptr = ...
    T += 1;
    Doit donner la même valeur que:
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    char * ptr = ...
    ptr += sizeof(T);
    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.

  9. #9
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par pasdeface Voir le message
    Bonjour

    Soit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    typedef struct _mastruct {
    	/* ... */
    }mastruct;
     
    mastruct *pointeur;
    J'ai une source dans laquelle il était écrit ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    read ( fd, (void*)((long)pointeur) + sizeof(mastruct), taille)
    Et ça fonctionne bien, mais j'ai besoin de l'écrire plus proprement car ce n'est plus accepté par mon compilateur.
    Est ce que vous pensez que j'obtiendrai le même fonctionnement en faisant ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    read ( fd, (unsigned char *)((long)pointeur) + sizeof(mastruct), taille)
    merci
    Sachant que je compile en C standard, je reproduis ton problème ainsi :
    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
     
    #include <stdio.h>
     
    typedef struct _mastruct
    {
       int dummy;
    }
    mastruct;
     
    int main (void)
    {
       FILE *fp = NULL;
       mastruct *pointeur = NULL;
     
       fread ((void *) ((long) pointeur) + sizeof (mastruct), 1, sizeof *pointeur, fp);
       return 0;
    }
    /* NE PAS EXECUTER */
    ce qui ne donne aucun warning

    Déjà, je retire le (void*) qui ne sert a rien, puisque le paramètre de données de read() (et de fread()) est de type void * : il accepte donc n'importe quelle adresse de données.

    Ensuite, le long ne sert à rien d'autre qu'à montrer qu'on a rien compris à l'arithmétique des pointeurs. On vire.

    Enfin, si on veut se décaler de une structure, on fait +1 avec un pointeur du bon type, comme nous l'enseigne la théorie de l'arithmétique des pointeurs. Ce qui donne en définitive :

    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
     
    #include <stdio.h>
     
    typedef struct _mastruct
    {
       int dummy;
    }
    mastruct;
     
    int main (void)
    {
       FILE *fp = NULL;
       mastruct *pointeur = NULL;
     
       fread (pointeur + 1, 1, sizeof *pointeur, fp);
       return 0;
    }
    Il n'y a donc aucune raison d'écrire du code plus compliqué que ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
       read (fd, pointeur + 1, sizeof *pointeur);

  10. #10
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    613
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2007
    Messages : 613
    Par défaut
    Merci pour les explications

    Citation Envoyé par Emmanuel Delahaye Voir le message
    Sachant que je compile en C standard, je reproduis ton problème ainsi :
    [...]
    ce qui ne donne aucun warning
    On peut reproduire mon problème de compilation en utilisant :
    -std=c89 -pedantic
    -> warning: pointer of type ‘void *’ used in arithmetic

  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
    En effet, l'addition sur un void* est une extension GNU.
    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.

  12. #12
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par pasdeface Voir le message
    On peut reproduire mon problème de compilation en utilisant :
    -std=c89 -pedantic
    -> warning: pointer of type ‘void *’ used in arithmetic
    Oui exact. Désolé, je n'ai pas l'habitude de voir un codage aussi tordu.

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 25/01/2011, 22h24
  2. Conversion string char[] pas très propre
    Par pasqual dans le forum Débuter
    Réponses: 4
    Dernier message: 17/09/2009, 08h19
  3. Conversion Long en int pas très propre !
    Par totoche dans le forum Débuter avec Java
    Réponses: 4
    Dernier message: 12/09/2008, 09h50

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