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 :

taille des pointeurs et des entiers


Sujet :

C++

  1. #1
    Membre actif
    Profil pro
    Étudiant
    Inscrit en
    Février 2005
    Messages
    263
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2005
    Messages : 263
    Points : 255
    Points
    255
    Par défaut taille des pointeurs et des entiers
    Bonjour,

    Je suis en train de développer une application en C++, avec g++ comme compilateur, et je me suis rendu compte d'une chose curieuse à mes yeux avec une version 64 bits:
    4 = __SIZEOF_INT__ != __SIZEOF_POINTER__ = 8
    Je pensais que sous 64 bits, un entier serait codé sur 8 octets, mais apparemment les développeurs ont préféré garder la taille maximale des int identiques sur les systèmes 64 et 32 bits (ce qui est pas tip top de mon point de vue, mais bon...)
    Du coup, je suis ennuyé car je transformais certains de mes pointeurs en entiers et ce n'est pas possible à moins de convertir les pointeurs en long, et les long en int.

    Ma question est donc la suivante: existe-t'il un moyen pour que les int soient codés sur la même taille que les pointeurs?

    Je sais que je pourrais définir mon propre type qui représenterait un entier de la même taille que les pointeurs, mais ça ferait pas très propre. Pour l'instant, la conversion pointeur->long->int est ce que j'ai trouvé de plus "propre" pour l'instant...

  2. #2
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Ma question est donc la suivante: existe-t'il un moyen pour que les int soient codés sur la même taille que les pointeurs?
    Utiliser un processeur 32 bits. Pour interchanger des int avec des adresses il faut être sûr que cela est sans danger pour la plateforme ciblée. Sur les proc (intel) 64 bits, interchanger des int avec des adresses n'a tout simplement (généralement) aucun sens car leurs tailles ne sont pas les mêmes. Quel est exactement ton but ? Et pour quel OS développes-tu ?

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Points : 1 176
    Points
    1 176
    Par défaut
    hmm il faut que l'on te le dise, mais tu n'es pas sensé stocker des pointeurs dans des entier

  4. #4
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    Je pensais que sous 64 bits, un entier serait codé sur 8 octets, mais apparemment les développeurs ont préféré garder la taille maximale des int identiques sur les systèmes 64 et 32 bits (ce qui est pas tip top de mon point de vue, mais bon...)
    Si le type int avait une taille de 64 bits, il ne resterait plus assez de types entiers (char, short) pour représenter les tailles inférieures (8, 16, 32). Certes ce n'est pas une obligation, mais j'imagine mal un système (hormis les trucs exotiques) qui ne fournirait pas de type pour l'une de ces tailles.

    Je sais que je pourrais définir mon propre type qui représenterait un entier de la même taille que les pointeurs, mais ça ferait pas très propre.
    Pourquoi pas ? Ce serait justement la solution la plus propre, et surtout la seule qui soit correcte. D'ailleurs il existe de tels types (inptr_t par exemple -- je ne sais pas s'il est standard).

  5. #5
    Expert éminent Avatar de Graffito
    Profil pro
    Inscrit en
    Janvier 2006
    Messages
    5 993
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2006
    Messages : 5 993
    Points : 7 903
    Points
    7 903
    Par défaut
    Peut-etre 2 solutions en compilant avec
    • gcc -m64 -o output64 ...
    • gcc -m32 -o output32 ...
    " Le croquemitaine ! Aaaaaah ! Où ça ? " ©Homer Simpson

  6. #6
    Membre actif
    Profil pro
    Étudiant
    Inscrit en
    Février 2005
    Messages
    263
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2005
    Messages : 263
    Points : 255
    Points
    255
    Par défaut
    wow, pas mal de réponse, c'est chouette

    Utiliser un processeur 32 bits. Pour interchanger des int avec des adresses il faut être sûr que cela est sans danger pour la plateforme ciblée. Sur les proc (intel) 64 bits, interchanger des int avec des adresses n'a tout simplement (généralement) aucun sens car leurs tailles ne sont pas les mêmes. Quel est exactement ton but ? Et pour quel OS développes-tu ?
    Le soucis, c'est que je contrôle pas le choix des processeur utilisé par ceux qui vont utiliser mon application J'utilise cette astuce pour avoir "gratuitement" des hash code de mes classes: je transforme l'adresse de this en entier. Je sais que l'idée même d'utiliser des pointeurs comme hash code n'est pas la plus brillante qui soit car ceux-ci ne seront pas bien répartis, mais bon. Je développe sous linux, mais j'aimerai (tant que possible) que ce soit compilable par tout système possédant gcc.

    hmm il faut que l'on te le dise, mais tu n'es pas sensé stocker des pointeurs dans des entier
    je tient à vous rassurer, une fois transformer en int, ceux-ci ne sont plus jamais utilisés comme pointeurs

    Si le type int avait une taille de 64 bits, il ne resterait plus assez de types entiers (char, short) pour représenter les tailles inférieures (8, 16, 32). Certes ce n'est pas une obligation, mais j'imagine mal un système (hormis les trucs exotiques) qui ne fournirait pas de type pour l'une de ces tailles.
    de mon point de vue, je trouve que la taille des données devrait varier en fonction des architectures. Et les types de données de taille spécifiques devrait être définis comme des types de données spécifiques comme le fais opengl avec int32_t par exemple.

    Je sais que je pourrais définir mon propre type qui représenterait un entier de la même taille que les pointeurs, mais ça ferait pas très propre.
    Pourquoi pas ? Ce serait justement la solution la plus propre, et surtout la seule qui soit correcte. D'ailleurs il existe de tels types (inptr_t par exemple -- je ne sais pas s'il est standard).
    Je préfèrerai garder le type 'int' car c'est ce que je veux obtenir, un entier. Définir un autre type nuirait à la lisibilité du code car dans certains cas les entiers sont des pointeurs 'castés', mais dans d'autres ce sont bel et bien des entiers.

    Peut-etre 2 solutions en compilant avec

    * gcc -m64 -o output64 ...
    * gcc -m32 -o output32 ...
    J'avais déjà vu ces options, mais le soucis c'est que:
    The 64-bit environment sets int to 32 bits and long and pointer to 64 bits and generates code for AMD's x86-64 architecture
    Pour l'instant, la solution la plus 'propre' serait d'utiliser des long au lieu de int car les long ont une taille égale au pointeurs pour les deux architectures...

  7. #7
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    de mon point de vue, je trouve que la taille des données devrait varier en fonction des architectures. Et les types de données de taille spécifiques devrait être définis comme des types de données spécifiques comme le fais opengl avec int32_t par exemple.
    Justement, s'il n'y a pas assez de types natifs pour créer les types int8_t, int16_t et int32_t, ça pose problème.

    Je préfèrerai garder le type 'int' car c'est ce que je veux obtenir, un entier. Définir un autre type nuirait à la lisibilité du code car dans certains cas les entiers sont des pointeurs 'castés', mais dans d'autres ce sont bel et bien des entiers.
    C'est pour ça que C++ définit plusieurs types d'entiers, se limiter à int est inutile.

    De toute façon le problème est simple :
    - soit ce que tu veux ce sont des int, peu importe que ce que tu mets dedans tienne ou pas --> utilise int et des casts pour y faire rentrer les types qui n'ont rien à voir (à tes risques et périls).
    - soit ce que tu veux c'est un type entier capable de stocker des addresses, et dans ce cas int n'est pas fait pour ça --> il te faut le type entier adéquat. Avec le typedef qui va bien je ne pense pas que ça nuise beaucoup à la lisibilité.

    Juste par curiosité, quelle est la finalité de la manip ?

  8. #8
    Membre actif
    Profil pro
    Étudiant
    Inscrit en
    Février 2005
    Messages
    263
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2005
    Messages : 263
    Points : 255
    Points
    255
    Par défaut
    Juste par curiosité, quelle est la finalité de la manip ?
    Le but est d'obtenir un haché pour les objets sans trop se casser la tête. Je sais que ce n'est vraiment pas la meilleure façon d'obtenir un haché car les derniers bits de différentes adresses seront identiques, mais en attendant, ça me permet d'obtenir ce que je veux de façon générique...
    Et puis, je me dit que cette idée ne doit pas être complètement mauvaise vu que c'est ça qui est utilisé par pour fournir des hachés d'objets en java comme on peut le lire dans la javadoc:
    typically implemented by converting the internal address of the object into an integer
    alors, je sais il y a de fortes chances pour que sur ce forum certain pensent "javasucks", mais bon

  9. #9
    Membre éprouvé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    780
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2006
    Messages : 780
    Points : 1 176
    Points
    1 176
    Par défaut
    Quel est ton besoin en fait? Plus précisément que "juste une hash map".

    tu as des objets de type heterogènes que tu veux stocker quelque part? mais tu fais quoi en particulier?

  10. #10
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Il existe un type entier standard qui a toujours la même taille qu'un pointeur: ptrdiff_t

  11. #11
    Expert éminent
    Avatar de Melem
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Janvier 2006
    Messages
    3 656
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Janvier 2006
    Messages : 3 656
    Points : 8 389
    Points
    8 389
    Par défaut
    Citation Envoyé par camboui Voir le message
    Il existe un type entier standard qui a toujours la même taille qu'un pointeur: ptrdiff_t
    Non, ptrdiff_t est le type du résultat de la différence entre deux pointeurs et la norme ne requiert pas que la taille de ce type soit égale à celle d'un pointeur. D'ailleurs la norme requiert même pas que tous les pointeurs aient la même taille.

    luckyvae : et le haché doit être un entier sur combien de bits ? Si c'est 32 bits, y'a pas de problème, tu cast l'adresse en int (32 bits). Si c'est 64 bits, tu cast l'adresse en entier 64 bits. Le type "entier 64 bits" dépend de ton compilateur. Dans Visual C++, c'est __int64. Dans g++, c'est long long (un type standard du C99).

  12. #12
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Citation Envoyé par Melem Voir le message
    Non, ptrdiff_t est le type du résultat de la différence entre deux pointeurs et la norme ne requiert pas que la taille de ce type soit égale à celle d'un pointeur. D'ailleurs la norme requiert même pas que tous les pointeurs aient la même taille.
    En pratique c'est le cas.
    Je veux bien qu'on me cite des compilos pour lesquels ce que tu dis est vrai, que je m'empresse de ne pas les utiliser.
    J'ai vécu l'époque des "near" et des "far", et même des "huge", je ne vois aucun intérêt à la ressuciter.

  13. #13
    Membre éclairé

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 717
    Points : 858
    Points
    858
    Par défaut
    Citation Envoyé par camboui Voir le message
    Je veux bien qu'on me cite des compilos pour lesquels ce que tu dis est vrai, que je m'empresse de ne pas les utiliser.
    VC++ et gcc notamment.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include <iostream>
     
    struct B {};
    struct A : virtual B {};
     
    int main()
    {
      std::cout << sizeof(int*) << ' ' << sizeof(int (A::*)());
    }
    Affiche "4 12" avec VC++ et "4 8" avec gcc.

  14. #14
    Membre actif
    Profil pro
    Étudiant
    Inscrit en
    Février 2005
    Messages
    263
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2005
    Messages : 263
    Points : 255
    Points
    255
    Par défaut
    Quel est ton besoin en fait? Plus précisément que "juste une hash map".
    tu as des objets de type heterogènes que tu veux stocker quelque part? mais tu fais quoi en particulier?
    Et bien j'ai différents types d'objets devant être insérés dans différentes hashmap. J'ai donc créé une hashmap avec des template pour la clé et la valeur, et je dois donc obtenir des haché des clés pour pouvoir les insérer dans ma map. Les clés peuvent être tout et n'importe quoi, du moment que l'on fournit un objet respectant une certaine interface.

    le haché doit être un entier sur combien de bits ?
    Ce que je voulais, c'est que la taille de ce haché ne soit pas fixé et dépendant de l'architecture. Et au moment où j'ai tout créé, je pensais que la taille des int dépendait de l'architecture, tout comme la taille des pointeurs. Mais, manque de chance, ce n'est pas le cas.

    Ce que j'ai donc fait maintenant, c'est d'utiliser des long qui eux ont la propriété que je voulais: ils ne sont pas de taille fixée, et sont de la même taille que les pointeurs. Du moins, en utilisant gcc sur des architectures de type 586 et x86_64...

  15. #15
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    Citation Envoyé par Sylvain Togni Voir le message
    VC++ et gcc notamment.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include <iostream>
     
    struct B {};
    struct A : virtual B {};
     
    int main()
    {
      std::cout << sizeof(int*) << ' ' << sizeof(int (A::*)());
    }
    Affiche "4 12" avec VC++ et "4 8" avec gcc.
    Yep un pointeur de fonction (fonction membre) n'est pas un pointeur comme les autres c'est pour ça..
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  16. #16
    Membre éprouvé
    Inscrit en
    Avril 2005
    Messages
    1 110
    Détails du profil
    Informations forums :
    Inscription : Avril 2005
    Messages : 1 110
    Points : 937
    Points
    937
    Par défaut
    Citation Envoyé par Sylvain Togni Voir le message
    VC++ et gcc notamment.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include <iostream>
     
    struct B {};
    struct A : virtual B {};
     
    int main()
    {
      std::cout << sizeof(int*) << ' ' << sizeof(int (A::*)());
    }
    Affiche "4 12" avec VC++ et "4 8" avec gcc.
    Tu me rassures. Les "pointeurs" des fonctions membres est un cas particulier. On ne peut d'ailleurs pas faire la différence entre deux pointeurs de fonction.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    int g1() {return 1;}
    int g2() {return 2;}
     
    int main()
    {
      int (* pg1)()=&g1;
      int (* pg2)()=&g2;
      std::cout << sizeof(pg1) << ' ' << sizeof(pg2) << std::endl;
      std::cout << pg1 << ' ' << pg2 << std::endl;
    //  std::cout << (pg1 - pg2) << std::endl; erreur compil
      return 0;
    }
    J'insiste, ptrdiff_t aura en pratique la taille de pointeurs qui peuvent s'additionner ou soustraire entre eux.

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

Discussions similaires

  1. Réponses: 18
    Dernier message: 01/04/2013, 17h07
  2. Des datagrid et des pointeurs
    Par HENRYC dans le forum C#
    Réponses: 2
    Dernier message: 26/02/2013, 18h39
  3. Manipulation des pointeurs sur des array of record
    Par kracter56 dans le forum Débuter
    Réponses: 8
    Dernier message: 13/04/2012, 09h58
  4. Map contenant des pointeurs sur des fonctions membres
    Par Bash01 dans le forum Débuter
    Réponses: 1
    Dernier message: 18/05/2010, 15h06
  5. Réponses: 1
    Dernier message: 27/11/2005, 14h30

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