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 :

dereferencing pointer....


Sujet :

C

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    237
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 237
    Par défaut dereferencing pointer....
    Bonjour a tous!

    J'ai un petit warning de compil en fait

    dereferencing pointer
    Et voici le bout de code associe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    float tmp =  4.2 ;                   // valeur quelconque pour l'exemple
    int *ptr_int = (int *)(&tmp) ;  // c'est ici qu'il y a un warning.
     
    toto[0] = (*ptr_int & 0x0FF000000) >> 24;
    En fait je voudrai recuperer l'adresse de mon float et la caster en int pour pouvoir faire un & binaire...

    Je ne vois pas trop l'erreur... et je ne comprends pas bien le warning..

    Merci de votre aide!!

  2. #2
    Membre émérite Avatar de 10_GOTO_10
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    890
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 890
    Par défaut Re: dereferencing pointer....
    Je ne comprends pas bien ce que tu veut faire: un & sur la valeur de tmp ou sur son adresse ?

    Dans le premier cas:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    float tmp =  4.2 ;
    int *ptr_int = (int *)(&tmp) ;
     
    toto[0] = ((*ptr_int) & 0x0FF000000) >> 24;
    et dans le second:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    float tmp =  4.2 ;
    int ptr_int = (int)(&tmp) ;
     
    toto[0] = (ptr_int & 0x0FF000000) >> 24;

  3. #3
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Par défaut
    Tu risques d'avoir une surprise, les float ne sont absolument pas codés comme les int, ce que tu vas obtenir ne correspond à rien !
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

  4. #4
    Membre émérite Avatar de 10_GOTO_10
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    890
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 890
    Par défaut
    Citation Envoyé par Trap D
    Tu risques d'avoir une surprise, les float ne sont absolument pas codés comme les int, ce que tu vas obtenir ne correspond à rien !
    Si, à l'exposant du float. Je pense que c'est le but de la manoeuvre (float = mantisse + exposant)

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    237
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 237
    Par défaut
    Si, à l'exposant du float. Je pense que c'est le but de la manoeuvre (float = mantisse + exposant)
    Exactement!

    Je ne comprends pas bien ce que tu veut faire: un & sur la valeur de tmp ou sur son adresse ?
    Je voudrai faire un & sur sa valeur.

    Mais l'exemple que tu donnes genere le meme warning.

    Tu risques d'avoir une surprise, les float ne sont absolument pas codés comme les int, ce que tu vas obtenir ne correspond à rien !
    Je ne sais pas trop comment m'y prendre en fait...
    Je suppose qu'il doit y avoir une methode "classique" pour ce genre d'operation.
    Quelqu'un la connait?

    Merci!!

  6. #6
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Par défaut
    Ok, je pensais que c'était pour avoir la valeur entière du float.
    Reçois toutes mes excuses vince3320.
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    237
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 237
    Par défaut
    Ok, je pensais que c'était pour avoir la valeur entière du float.
    Reçois toutes mes excuses vince3320.
    Rooo!
    Pas besoin de s'excuser!
    Merci quand meme!

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    237
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 237
    Par défaut
    float * ptr;
    ptr = &tmp;
    Oui mais j'en fais quoi apres de mon float?

    On ne peut pas faire de & binaire sur un float il me semble...

    Du coup, je dois declarer ptr en int (voir int *) et mon probleme reste le meme...

    A moins que je n'ai rien compris a ce que tu viens de marquer...

  9. #9
    Membre émérite Avatar de 10_GOTO_10
    Profil pro
    Inscrit en
    Juillet 2004
    Messages
    890
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2004
    Messages : 890
    Par défaut
    Avec quel compilateur as-tu l'erreur ?

    Moi, je l'ai compilé avec Builder Borland et Visual C Microsoft, et je n'ai aucune erreur de ce type (avec ou sans les parenthèses, d'ailleurs). Seule erreur en Visual:

    'initializing' : truncation from 'const double ' to 'float '
    Que j'ai corrigé en mettant:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    float tmp = (float) 4.2 ;

  10. #10
    Membre éclairé Avatar de Biosox
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    298
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 298
    Par défaut
    j'avais répondu et vite supprimé ce que j'ai écrit apres m'être relu voici une meilleure réponse:

    je voudrai recuperer l'adresse de mon float et la caster en int
    mais l'adresse de ton float c'est déja un int!
    une adresse est un entier dont la valeur numérique correspond à une position dans la mémoire.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    float tmp = 4.2; //tmp est un float.
    float * ptr = &tmp // ptr est un pointeur vers ton float: c'est un entier qui contient l'adresse de tmp
    si tu fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    float tmp = 4.2; //tmp est un float.
    int* ptr = &tmp // ca marche, mais le compilateur "voit" que tu veux pointer vers un int et "voit" que tmp est un float, d'ou le warning
    en fait, des que tu mets une*, tu as un pointeur, donc un entier:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    char* ptr_c //ptr_c est un entier, qui est supposé pointer vers un char
    int* ptr_i //ptr_i est un entier, qui est supposé pointer vers un emtier
    float* ptr_f //ptr_f est un entier, qui est supposé pointer vers un float
    short* ptr_s //ptr_s est un entier, qui est supposé pointer vers un short
    dans tout les cas, tu peux les faire pointer ou tu veux, puisque un pointeur vers n'importe quoi est un entier, 32 bits, le compilateur est d'accord, mais il met un warning, car en faisant la déclaration, tu lui dit vers quoi tu veux pointer, et si tu pointe vers autre chose, il te prévient. mais ça marche

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    237
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 237
    Par défaut
    Avec quel compilateur as-tu l'erreur ?
    gcc 3.4.3

    Par contre, j'ai oublie de preciser un detail..

    En fait, ce code marche sur solaris 32bits.
    Il n'y a aucun warning mais c'est un vieux gcc (2.9)
    Du coup, je ne sais pas si avec le meme gcc j'aurai aussi le warning...

    Et la je suis en train de le porter sous linux 64 bits avec gcc 3.4.3
    J'obtiens alors ce warning.

    Si je passe outre ce warning et que je lance le programme, tout se passe bien et les resultats sont corrects!
    Mais ce n'est pas une bonne solution!

  12. #12
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    237
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 237
    Par défaut
    mais l'adresse de ton float c'est déja un int!
    une adresse est un entier dont la valeur numérique correspond à une position dans la mémoire.
    Je suis completement d'accord!

    dans tout les cas, tu peux les faire pointer ou tu veux, puisque un pointeur vers n'importe quoi est un entier, 32 bits, le compilateur est d'accord, mais il met un warning, car en faisant la déclaration, tu lui dit vers quoi tu veux pointer, et si tu pointe vers autre chose, il te prévient. mais ça marche
    Du coup, si je suis ton idee et que je l'ai bien comprise, cela donnerait :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    float tmp = 4.2;
    float *ptr_float = &tmp ; 
    toto[0] = (*ptr_float & 0x0FF000000) >> 24;
    Mais ceci ne marche pas et j'obtiens le message suivant :
    erreur : operandes invalides pour le binaire &
    Ce qui veut dire que le type n'est pas le bon.
    Je pense que je dois declarer un int...

    Ou alors est ce liee au fait que je sois sur 64 bits?
    Ou c'est autre chose?

  13. #13
    Membre éclairé Avatar de Biosox
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    298
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 298
    Par défaut
    effectivement, je n'ai pas trop regardé ce que tu voulais faire avec ton adresse. le problème c'est celui-ci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    float * ptr = &tmp;
    /* donc 'ptr' est un entier, mais '*ptr' est bien un float. */
     
    (*ptr_float & 0x0FF000000)
    /*erreur: *ptr et 0xFF000000 n'utilisent pas le même nombre de bits*/
    je ne comprend pas bien ce que tu veux faire. en fait tu voudrais faire un "and binaire" sur le premier octet de ton float?

    si c'est le cas, soit tu te contentes du warning en gardant ton code d'avant, soit tu crées un int avec le contenu de ce vers quoi ptr pointe:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    int monEntier=(int)*ptr;
    /*ensuite tu fait ton AND avec 'monEntier*/
    si je ne me trompe pas, monEntier devrait contenir la mantisse de ton float, mais je ne suis plus trop sur de la manière dont les float sont stockés en mémoire.

  14. #14
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    237
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 237
    Par défaut
    Rooo!
    Enorme!

    Merci beaucoup!
    Ca marche nickel!

    J'aurai une question du a ma curiosite :

    Et si a la place des float, j'avais des double?
    Il y aurait une solution?

  15. #15
    Membre éclairé Avatar de Biosox
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    298
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 298
    Par défaut
    c'est toujours possible. le problème c'est de savoir la représentation de tes variables en mémoire:
    La taille des types n’est spécifiée dans aucune norme. La seule chose qui est indiquée dans la norme
    C++, c’est que le plus petit type est le type char. Les tailles des autres types sont donc des multiples
    de celle du type char. De plus, les inégalités suivantes sont toujours vérifiées :
    char<=short int<=int<=long int
    float<=double<=long double
    du coup je ne sais pas comment savoir la représentation d'un double.
    avec sizeof(double) on connait la taille en octet, mais pour savoir combien d'octet utilise la mantisse et ou elle se trouve, et si elle prend plus d'un octet, est-elle notée en big ou little endian, etc etc... il faut fair quelques tests pour savoir tout ça. Mais une fois que tu le sais, tu peux toujours utiliser des pointeurs comme avant. Il faut aussi savoir que le type que tu utilise pour définir ton pointeur donnera une indication pour l'incrémentation:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    double temp=4,2;
    int * ptr_int = &temp //un warning, mais ptr_int pointe au début de temp
    char * ptr_char = &temp //idem
     
    ptr_int++; //ptr_int pointe 4 octets plus loin
    ptr_char++; //ptr_char point 1 octet plus loin
    /*a condition que sizeof(char)=1 et sizeof(int)=8*/
    ainsi, tu peux parcourir par exemple ton double octet par octet, ou 4 octets par 4 octets...

  16. #16
    Membre confirmé
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    237
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 237
    Par défaut
    Merci a toi encore une fois!
    Je vais regarder tout ca!

  17. #17
    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 Biosox
    du coup je ne sais pas comment savoir la représentation d'un double.
    avec sizeof(double)
    La taille et l'emplacement des champs sont définis dans <float.h>

  18. #18
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    vince3320 :
    Citation: Biosox
    mais l'adresse de ton float c'est déja un int!
    une adresse est un entier dont la valeur numérique correspond à une position dans la mémoire.
    Je suis completement d'accord!
    Moi pas du tout! L'arithmétique des adresses n'a rien à voir avec celle des int. Si tu veux dire qu'une adresse est représentée par une configuration de bits en mémoire que tu interprètes comme un int (!), c'est valable pour n'importe quoi. Assimiler une adresse à un int (ou le contraire) n'est tolérable que pour la valeur 0 (en assimilant celà à un transtypage implicite de la valeur int 0 à une adresse NULL). Sinon, on retombe dans les mic-mac des pionniers du C, en allant à l'encontre de la tendance actuelle (bienvenue) favorisant la rigueur et l'abstraction de la programmation. On peut, pour une application bas-niveau (ce qui est ici le cas) se livrer à pareille magouille, mais on doit rester conscient qu'il s'agit d'une magouille et qu'une adresse n'est PAS un int.

  19. #19
    Expert éminent
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 391
    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 391
    Par défaut
    Enfin, ici, ce que vince3320 cherche à faire, ce n'est pas manipuler le pointeur comme un int (c'est Biosox qui avait mal lu), mais accéder à un flottant avec un pointeur vers int, car c'est l'unique moyen d'avoir accès à ses données brutes (un bête transtypage en int entraînant une conversion, le int contienant alors la valeur entière).

    J'avais fait la même chose suite à un TP nous ayant appris la structure standard des flottants 16 et 32 bits, mais je n'avais pas eu ce genre de warning... :
    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.

  20. #20
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    Enfin, ici, ce que vince3320 cherche à faire, ce n'est pas manipuler le pointeur comme un int
    Oui, je comprends très bien ceci et je ne critique pas à priori ce genre de choses si elles sont faites en connaissance de cause. Mais, affirmer qu'un adresse est un int : NON. Il est possible de faire ce genre de choses, mais il faut être conscient qu'il s'agit là d'un procédé anormal justifié par le but à atteindre. Affirmer qu'une adresse est équivalente à un int et est manipulable comme tel: NON.

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

Discussions similaires

  1. error: dereferencing pointer to incomplete type
    Par Amnael dans le forum Débuter
    Réponses: 15
    Dernier message: 16/03/2014, 23h26
  2. dereferencing pointer to incomplete type
    Par Almenor dans le forum Débuter
    Réponses: 10
    Dernier message: 31/05/2012, 10h17
  3. dereferencing pointer to incomplete type
    Par Anasiben dans le forum Débuter
    Réponses: 3
    Dernier message: 19/05/2011, 16h39
  4. forward declaration et error: dereferencing pointer
    Par vincent.mbg dans le forum C
    Réponses: 4
    Dernier message: 15/06/2010, 12h57
  5. dereferencing pointer to incomplete type
    Par Newgaia dans le forum Débuter
    Réponses: 2
    Dernier message: 19/04/2009, 19h00

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