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 :

Les type de pointeurs vis à vis de la compilation


Sujet :

C

  1. #1
    Membre habitué Avatar de dafpp
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2008
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2008
    Messages : 345
    Points : 196
    Points
    196
    Par défaut Les type de pointeurs vis à vis de la compilation
    Bonjour,
    je me demandais si le fait de mettre un pointeur de type avait une quelconque incidence. Pour moi, l'espace mémoire est réservé selon l'arch, mais vu que c'est un pointeur, l'espace mémoire indique une adresse. Mais rien ne permet de savoir le type de l'adresse. Ça peut être n'importe quoi.
    Exemple: void * pointeur;
    Et si j'utilise le pointeur pour des entiers ou des caractères, ça n'a pas d'importance. On est d'accord qu'à part quelque warning de la part du compilateur, rien ne changera? Est-ce conseillé ou non?

    Libere,
    Dafpp.
    "Les spécialistes commencent par n'apprendre que ce qu'ils aiment et finissent par n'aimer que ce qu'ils ont appris." - Gilbert Cesbron
    "Si nous avons chacun un objet et que nous les echangeons, nous avons chacun un objet. Si nous avons chacun une idée et que nous les échangeons, nous avons chacun deux idées." - Proverbe Chinois.

  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
    pointeur++ ne marchera pas pour void* (sauf en GNU C, il me semble) et l'incrément changera selon la taille du pointeur.

    Edit: Aussi, void* n'est pas déréférençable, donc dans tous les cas tu devras passer par un cast... Autant se passer du cast dès le début.
    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
    Membre habitué Avatar de dafpp
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2008
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2008
    Messages : 345
    Points : 196
    Points
    196
    Par défaut
    C'était un exemple void.
    Moi je considère que par la suite on indique toujours le type : (int)pointeur++. Ça marche non?
    "Les spécialistes commencent par n'apprendre que ce qu'ils aiment et finissent par n'aimer que ce qu'ils ont appris." - Gilbert Cesbron
    "Si nous avons chacun un objet et que nous les echangeons, nous avons chacun un objet. Si nous avons chacun une idée et que nous les échangeons, nous avons chacun deux idées." - Proverbe Chinois.

  4. #4
    Expert éminent sénior
    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
    Points : 13 926
    Points
    13 926
    Par défaut
    Bien sûr qu'il y a une incidence :

    1- le type permet au compilateur de connaitre le type de l'objet dont on a l'adresse. Non seulement, cela lui permet de connaitre la taille mémoire occupée par l'objet placé à cette adresse, mais aussi les opérations permises et utilisable avec cet objet
    Par exemple, l'évaluation de l'expression 1 + *pb dépendra du type du pointeur pb.
    Si pb est du type int *, alors le compilateur sait que l'objet à l'adresse pb est un entier et il peut aller le chercher comme tel et faire l'opération entre le int 1 et le int *pb. L'opérateur + est l'addition entre entier et le résultat est un entier
    Si pb est de type float * , *pb est considéré comme un float et sera lu dans la mémoire comme tel. L'expression sera évaluée par conversion du int 1 en float. L'opérateur + est l'addition entre float et le résultat est un float.

    2- le type intervient (de façon implicite) dans les opérations sur les adresses :
    Si on écrit 1+ pb, où pb est un pointeur, l'adresse obtenue dépend directement du type du pointeur pb

    Moi je considère que par la suite on indique toujours le type : (int)pointeur++. Ça marche non?
    Très mauvaise idée que de caster le pointeur. L'utilisation de cast explicite empêche le compilateur de faire une foule de contrôles sur la cohérence du code : il est forcé de nous croire sur parole. L'utilisation des cast explicites est à limiter strictement aux cas où on ne peut pas faire autrement (comme par exemple le cast d'un pointeur void * vers le type effectif de l'objet pointé)
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

  5. #5
    Membre habitué Avatar de dafpp
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2008
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2008
    Messages : 345
    Points : 196
    Points
    196
    Par défaut
    • Donc pour le compilateur et être sûr de ne pas faire n'importe quoi, faut pas le faire. Mais le compilateur comprendra : 1 + (int)*nb avec nb de type void *
    • oui comme disait Médinoc.


    C'est noté. C'est après une discussion sur le langage C. Je savais que ça se faisait, mais à savoir si c'était correcte jusqu'au compilateur, ça je n'étais pas sûr.
    "Les spécialistes commencent par n'apprendre que ce qu'ils aiment et finissent par n'aimer que ce qu'ils ont appris." - Gilbert Cesbron
    "Si nous avons chacun un objet et que nous les echangeons, nous avons chacun un objet. Si nous avons chacun une idée et que nous les échangeons, nous avons chacun deux idées." - Proverbe Chinois.

  6. #6
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Les pointeurs void* sont un peu à part, il sont justement là pour remplacer n'importe quel type de pointeurs. Mais une fois casté (et tu es obligé de le faire pour accéder à la variable pointée), on retrouve un pointeur "normal" qui est bien l'agrégat d'une adresse et d'une description de type.

    Si ta question concerne la validité d'un code tel que:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    int a = 42;
    void *pv = &a;
     
    int *pa = &a;
    void pva = pa;
    alors la réponse est "c'est valide" car n'importe quel pointeur peut être converti en un void*.

    Je me demande comment se passe l'inverse si tu ne mets pas de caste explicite... gcc semble accepter.

  7. #7
    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
    ↑C'est légal en C, mais en C++ il faut au moins un static_cast.
    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.

  8. #8
    Membre habitué Avatar de dafpp
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2008
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2008
    Messages : 345
    Points : 196
    Points
    196
    Par défaut
    Jamais fais de C++. Mais c'est noté.
    "Les spécialistes commencent par n'apprendre que ce qu'ils aiment et finissent par n'aimer que ce qu'ils ont appris." - Gilbert Cesbron
    "Si nous avons chacun un objet et que nous les echangeons, nous avons chacun un objet. Si nous avons chacun une idée et que nous les échangeons, nous avons chacun deux idées." - Proverbe Chinois.

  9. #9
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Points : 2 505
    Points
    2 505
    Par défaut
    Pour corriger ce qui a été dit plus haut, on peut tout à fait faire de l'arithmétique sur un pointeur void *. C'est comme faire de l'arithmétique sur un char * (c'est à dire qu'ajouter 1 à un void * ajoute 1 à la valeur du pointeur). Par contre évidemment, comme ça a déjà été dit, on ne peut pas déréférencer puisqu'on ne connaît pas la taille du type référencé.

    En fait c'est peu connu, et on voit souvent du code qui utilise des char * pour faire de l'arithmétique sur des types "opaques". C'est dommage car utiliser un char * implique de recaster explicitement le résultat avant de pouvoir en faire quelque chose. Avec un void * le cast est implicite, ce qui simplifie l'écriture.

  10. #10
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #include <stdio.h>
    #include <stdlib.h>
     
    int main(void)
    {
        const char * chaine = "Bonjour";
        const void * p = chaine;
        p++;
        return 0;
    }
    émet un warning :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    D:\\main.c||In function 'main':|
    D:\\main.c|8|warning: wrong type argument to increment [-pedantic]|
    ||=== Build finished: 0 errors, 1 warnings (0 minutes, 0 seconds) ===|
    En regardant le warning sur le net, je trouve que c'est une extension gcc : http://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html

  11. #11
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Points : 2 505
    Points
    2 505
    Par défaut
    Exact, j'étais sûr d'avoir lu dans la norme que l'arithmétique était valide sur un void *, mais ce n'est pas le cas. Désolé

  12. #12
    Membre habitué Avatar de dafpp
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2008
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2008
    Messages : 345
    Points : 196
    Points
    196
    Par défaut
    Mais dans ce cas que ça soit char ou void, p++ fera la même chose non? Il se déplace de une adresse?
    Et je ne sais jamais, dans l'exemple, le const concerne quoi? L'adresse du pointeur ou la valeur du pointeur?
    "Les spécialistes commencent par n'apprendre que ce qu'ils aiment et finissent par n'aimer que ce qu'ils ont appris." - Gilbert Cesbron
    "Si nous avons chacun un objet et que nous les echangeons, nous avons chacun un objet. Si nous avons chacun une idée et que nous les échangeons, nous avons chacun deux idées." - Proverbe Chinois.

  13. #13
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Ce qui est a droite de l'étoile concerne le pointeur, ce qui est a gauche concerne les variables pointées. Donc ici, les pointeurs ne sont pas constants.

    L'incrementation sera la même si tu as gcc et en utilises les extensions.

  14. #14
    Membre habitué Avatar de dafpp
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2008
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2008
    Messages : 345
    Points : 196
    Points
    196
    Par défaut
    Citation Envoyé par Bktero Voir le message
    Ce qui est a droite de l'étoile concerne le pointeur, ce qui est a gauche concerne les variables pointées. Donc ici, les pointeurs ne sont pas constants.

    L'incrementation sera la même si tu as gcc et en utilises les extensions.
    Merci pour les précisions.
    "Les spécialistes commencent par n'apprendre que ce qu'ils aiment et finissent par n'aimer que ce qu'ils ont appris." - Gilbert Cesbron
    "Si nous avons chacun un objet et que nous les echangeons, nous avons chacun un objet. Si nous avons chacun une idée et que nous les échangeons, nous avons chacun deux idées." - Proverbe Chinois.

  15. #15
    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
    Citation Envoyé par dafpp Voir le message
    Mais dans ce cas que ça soit char ou void, p++ fera la même chose non? Il se déplace de une adresse?
    Avec un compilateur autre que gcc, l'incrémentation sur void* ne compilera même pas (erreur C2036 sous Visual, par exemple).
    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.

  16. #16
    Membre habitué Avatar de dafpp
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2008
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2008
    Messages : 345
    Points : 196
    Points
    196
    Par défaut
    Citation Envoyé par Médinoc Voir le message
    Avec
    un compilateur autre que gcc, l'incrémentation sur void* ne compilera
    même pas (erreur C2036 sous Visual, par exemple).
    Bah pourquoi ça? '++' permet de se déplacer d'une adresse et se placer sur le 'o'? Donc void ou int ou float ça change rien? si?
    "Les spécialistes commencent par n'apprendre que ce qu'ils aiment et finissent par n'aimer que ce qu'ils ont appris." - Gilbert Cesbron
    "Si nous avons chacun un objet et que nous les echangeons, nous avons chacun un objet. Si nous avons chacun une idée et que nous les échangeons, nous avons chacun deux idées." - Proverbe Chinois.

  17. #17
    Membre émérite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Octobre 2008
    Messages
    1 515
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 515
    Points : 2 505
    Points
    2 505
    Par défaut
    Le comportement n'est pas défini par le standard, donc chaque compilo peut faire ce qui lui plaît. Et en passant, l'incrémentation d'un pointeur ne permet pas de "passer à l'adresse suivante", elle incrémente l'adresse de la taille du type pointé.

    Ceci dit dire que ça ne marche qu'avec GCC est faux également, puisque ça marche aussi avec XLC. Et je suis sûr que de nombreux autres compilateurs supportent également l'arithmétique sur les void *.

  18. #18
    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
    Citation Envoyé par dafpp Voir le message
    Bah pourquoi ça? '++' permet de se déplacer d'une adresse et se placer sur le 'o'? Donc void ou int ou float ça change rien? si?
    L'incrémentation sur un pointeur augmente de la taille, pas de 1.
    Le type "void" n'a pas de taille.
    Une structure déclarée mais non définie (alias "type incomplet") n'en a pas non plus, d'ailleurs.
    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.

  19. #19
    Membre habitué Avatar de dafpp
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2008
    Messages
    345
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2008
    Messages : 345
    Points : 196
    Points
    196
    Par défaut
    Ha oui! en effet. Donc le type est plus qu'important.

    Donc gcc compile car il sait que le pointeur pointe vers une zone mémoire de type char, et donc cast automatiquement?
    "Les spécialistes commencent par n'apprendre que ce qu'ils aiment et finissent par n'aimer que ce qu'ils ont appris." - Gilbert Cesbron
    "Si nous avons chacun un objet et que nous les echangeons, nous avons chacun un objet. Si nous avons chacun une idée et que nous les échangeons, nous avons chacun deux idées." - Proverbe Chinois.

  20. #20
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Non. Il considère lors d'un ++ sur un pointeur sur void qu'il faut incrémenter de 1. C'est la même incrémentation que pour un pointeur sur char mais ça ne veut pas dire que void* et char* sont pareils. Et ça ne veut pas dire qu'il sait sur quoi ça pointe. Dans ton cas, c'est un char, ça marche pareil et c'est de la chance. Si ça pointait sur des int, ça ferait n'importe quoi.

    C'est comme dire int et float, c'est pareil. Non, ça s'incrémente juste pareil.

Discussions similaires

  1. Pourquoi les entreprises françaises sont-elles si réticentes vis-à-vis du télétravail ?
    Par Katleen Erna dans le forum Forum général Solutions d'entreprise
    Réponses: 19
    Dernier message: 31/12/2019, 11h33
  2. [Débutant][Phppgadmin] problème avec les types
    Par PoY dans le forum PostgreSQL
    Réponses: 3
    Dernier message: 19/08/2004, 17h06
  3. indépendance vis à vis de ODBC
    Par ka0z dans le forum ASP
    Réponses: 2
    Dernier message: 08/06/2004, 16h56
  4. Comparer les types de variable
    Par onipif dans le forum ASP
    Réponses: 11
    Dernier message: 27/05/2004, 18h07
  5. fopen -> différences entres les types d'ouvertur
    Par Patrick PETIT dans le forum C
    Réponses: 10
    Dernier message: 01/06/2003, 18h19

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