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 :

problème de pointeur


Sujet :

C

  1. #1
    Membre chevronné
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 854
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 854
    Par défaut problème de pointeur
    bonjour,

    pour ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    UINT32 *ptReg;
    ptReg = (UINT32*)&REGX; // REGX est un registre
    J'ai le warning suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    warning: dereferencing type-punned pointer will break strict-aliasing rules
    ça veut dire quoi exactement ?
    Remarque : en remplaçant (UINT32*) par (void*) je n'ai plus le message d'erreur.
    Que faut-il que je mette pour avoir un codage propre ?

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    60
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 60
    Par défaut
    Bonjour,

    Si tu es sous 'gcc', essaie avec l'option
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    $ gcc --fno-strict-aliasing  ... (la suite) ...

  3. #3
    Membre chevronné
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 854
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 854
    Par défaut
    En fait le compilo n'est pas réellement gcc mais une version modifiée de gcc.

    La ligne de commande suivante me génère une erreur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    "C:\Program Files\Microchip\MPLAB C32\bin\pic32-gcc.exe" -mprocessor=32MX695F512L -x c -c "CustomHTTPApp.c" -o"Objects\CustomHTTPApp.o" -MMD -MF"Objects\CustomHTTPApp.d" -I"." -I"..\Microchip\Include"  -g -D --fno-strict-aliasing -Wall -Os
    <command line>:1:1: macro names must be identifiers
    => est-ce que ça veut dire que mon compilo ne supporte pas cette option ou est-ce que j'ai mal écrit ma ligne de commande ?


    => j'ai vu sur le net que cette commande sert à supprimer les warning mais j'aimerais quand même savoir ce qu'il se passe exactement (le pourquoi du comment)...

  4. #4
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 830
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 830
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par boboss123 Voir le message
    bonjour,

    pour ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    UINT32 *ptReg;
    ptReg = (UINT32*)&REGX; // REGX est un registre
    J'ai le warning suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    warning: dereferencing type-punned pointer will break strict-aliasing rules
    ça veut dire quoi exactement ?
    Salut

    Ca signifie que le cast de ton adresse &REGX en pointeur sur un UINT32 fait perdre la notion de l'objet pointé. Il est probable que REGX n'est pas de type UINT32 et le compilo te prévient qu'en faisant ça, il ne te garanti pas le bon résultat si tu demandes ensuite "*ptReg"

    Citation Envoyé par boboss123 Voir le message
    Remarque : en remplaçant (UINT32*) par (void*) je n'ai plus le message d'erreur.
    Normal. Un pointeur void* est un pointeur universel. Dans ce cas là tu spécifies explicitement "je sais que je fais un truc compliqué mais je gère". Donc le compilo te laisse tranquille.

    Citation Envoyé par boboss123 Voir le message
    Que faut-il que je mette pour avoir un codage propre ?
    Il faut déjà savoir ce qu'est REGX et pourquoi tu veux transformer un pointeur d'un type X en pointeur de type UINT32...

    Citation Envoyé par boboss123 Voir le message
    mais j'aimerais quand même savoir ce qu'il se passe exactement (le pourquoi du comment)...
    Très bonne démarche. J'en connais qui ne veulent absolument pas se préoccuper de la cuisine interne mais qui se permettent quand-même d'asséner des affirmations péremptoires du haut de leur vanité. Mais eux,
    un jour ou l'autre ils se font allumer par ceux qui, comme toi, cherchent à comprendre...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  5. #5
    Membre chevronné
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 854
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 854
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Il faut déjà savoir ce qu'est REGX et pourquoi tu veux transformer un pointeur d'un type X en pointeur de type UINT32...
    En fait dans mon µControlleur, j'ai plusieurs registres qui se suivent : REG0, REG1, REG2, ...
    Ce que je voulais faire, c'est mettre l'adresse du registre dans un pointeur puis de faire la boucle suivante pour récupérer les différentes valeurs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    UINT32 *ptReg;
    ptReg = (UINT32*)&REGX; // REGX est un registre
    for(i=0; i<nbReg; i++){
        tab[i] = *ptReg++; 
    }
    => j'ai défini le pointeur en UINT32* car les registres sont de 32bits : est-ce qu'il y a une meilleure méthode pour faire cela (je ne sais pas qu'il est le type d'un registre) ?

  6. #6
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 830
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 830
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par boboss123 Voir le message
    En fait dans mon µControlleur, j'ai plusieurs registres qui se suivent : REG0, REG1, REG2, ...
    Ce que je voulais faire, c'est mettre l'adresse du registre dans un pointeur puis de faire la boucle suivante pour récupérer les différentes valeurs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    UINT32 *ptReg;
    ptReg = (UINT32*)&REGX; // REGX est un registre
    for(i=0; i<nbReg; i++){
        tab[i] = *ptReg++; 
    }
    => j'ai défini le pointeur en UINT32* car les registres sont de 32bits : est-ce qu'il y a une meilleure méthode pour faire cela (je ne sais pas qu'il est le type d'un registre) ?
    Ok, je vois ce que tu veux faire. Il est probable que ton UINT32 est de la bonne taille mais comme le compilo ne le sait pas, il te met le warning.

    Maintenant, pourquoi t'embêter à "recopier" la valeur de tes registres dans ton tableau ???
    T'as qu'à stocker directement les adresses dans un tableau de pointeurs void * ce qui évite de "présupposer" de la taille de ton registre

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    void *tabReg[nbReg];
    size_t i;
    void *ptReg;
    ptReg=&REGX;     => tu stockes l'adresse d'un truc que tu ne connais pas dans une zone prévue pour recevoir un pointeur universel => zéro soucy
    for (i=0; i < nbReg; i++)
    {
        // Maintenant on stocke le pointeur dans le tableau
        tab[i]=ptReg;
     
        // Ensuite on décale le pointeur de "taille d'un registre" (compté en char)
        ptReg=(char*)ptReg + sizeof(REGX);
    }
     
    // Ici, toutes tes adresses sont mémorisées

    Ensuite, le problème ne se posera que si tu veux récupérer la valeur du registre x. A ce moment là, tu devras taper dans "*tab[x]" et là, tu seras obligé de faire une supposition de la taille de la zone. Si tu imagines que c'est de l'UINT32 alors tu casteras le pointeur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("%d", *(UINT32*)(tab[x]));
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  7. #7
    Membre chevronné
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 854
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 854
    Par défaut
    ok merci

  8. #8
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 830
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 830
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par boboss123 Voir le message
    ok merci
    A la réflexion, pourquoi même recopier toutes les adresses puisque toutes sont dépendantes de la première ??? Te suffit de garder simplement la première

    Ensuite, si tu veux la "n" ième valeur, alors te suffit de demander
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("%d", *(UINT32*)((char*)ptReg + x * sizeof(REGX)))
    Et en réfléchissant tout à fait, ça ne sert pas à grand chose non plus de mémoriser la première adresse puisqu'on l'à déjà
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    printf("%d", *(UINT32*)((char*)(&REGX) + x * sizeof(REGX)))
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  9. #9
    Membre chevronné
    Profil pro
    Inscrit en
    Septembre 2009
    Messages
    1 854
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2009
    Messages : 1 854
    Par défaut
    ok

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

Discussions similaires

  1. Problème de pointeurs..embrouillé
    Par Frenchy dans le forum C++
    Réponses: 11
    Dernier message: 10/03/2005, 16h33
  2. Problème de pointeur avec un TQuery
    Par Oluha dans le forum Bases de données
    Réponses: 3
    Dernier message: 25/01/2005, 13h57
  3. Problème de pointeur
    Par toma_lille dans le forum C++
    Réponses: 1
    Dernier message: 07/12/2004, 21h26
  4. [MFC] Problème de pointeur !!
    Par acastor dans le forum MFC
    Réponses: 7
    Dernier message: 19/03/2004, 15h50
  5. TBitmap et problèmes de pointeurs...
    Par benj63 dans le forum C++Builder
    Réponses: 8
    Dernier message: 28/07/2003, 13h39

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