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 :

struct et alignement


Sujet :

C++

  1. #1
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut struct et alignement
    Bonjour,
    est'il possible de spécifier l'alignement des variables d'une structure, pour que le compilot ne puisse pas les aligner comme il le souhaite et par exemple, donner un espace de 32bit pour un char (ce qui agrandi la taille mémoire d'un structure)?
    J'ai eu ce problème avec libjpeg où la taille de la structure dans mon programme n'était pas la même que celle de la lib compilé à cause de ces alignement.

    merci

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 376
    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 376
    Points : 41 544
    Points
    41 544
    Par défaut
    Dépend du compilo.

    Sous gcc, on ajoute __attribute__((packed)) (ou un truc du genre) à la structure.

    Sous Visual, c'est un truc de ce genre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #include <pshpack1.h> //Existe aussi 2, 4, et peut-être 8
     
    struct uneStructure
    {
    char unChar;
    int unInt;
    };
     
    #include <poppack.h>
    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
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    merci.
    on ma parlé aussi d'une écriture un peu obscure
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct uneStructure
    {
    char unChar :2;
    int unInt :4;
    };

    mais je ne comprend pas a quoi sert les ": x" et si c'est lié à l'alignement

  4. #4
    Membre éclairé Avatar de valefor
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    711
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 711
    Points : 790
    Points
    790
    Par défaut
    Les ":" servent à faire des bitfields, donc ça ne sert pas à gérer l'alignement.

    Dans ton exemple unChar fera 2 bits, et unInt 4.

    Perso, je trouve cette notation de bitfield atrocement compliqué à comprendre (à cause des problèmes d'endianess, d'alignement, et autres choses obscures qui ne sont pas portables d'un compilo/plateforme/... à l'autre).

  5. #5
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 376
    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 376
    Points : 41 544
    Points
    41 544
    Par défaut
    Non, ce sont les "champs de bits".

    Malheureusement, ce n'est pas portable: Le standard ne garantit pas l'ordre des champs, etc. Donc, on peut utiliser ça pour faire des structures plus petites si on a trois fois rien à mettre dedans, mais il est déconseillé de s'en servir pour accéder à des registres de périphériques, 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.

  6. #6
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par valefor Voir le message
    Les ":" servent à faire des bitfields, donc ça ne sert pas à gérer l'alignement.

    Dans ton exemple unChar fera 2 bits, et unInt 4.

    Perso, je trouve cette notation de bitfield atrocement compliqué à comprendre (à cause des problèmes d'endianess, d'alignement, et autres choses obscures qui ne sont pas portables d'un compilo/plateforme/... à l'autre).
    juste pour être sur de comprendre 8bits = 1 byte ="taille d'un char" ?



    Citation Envoyé par Médinoc Voir le message
    Non, ce sont les "champs de bits".

    Malheureusement, ce n'est pas portable: Le standard ne garantit pas l'ordre des champs, etc. Donc, on peut utiliser ça pour faire des structures plus petites si on a trois fois rien à mettre dedans, mais il est déconseillé de s'en servir pour accéder à des registres de périphériques, par exemple...
    tu veut dire quand on utilise les "champs de bits" ? ou en général?

  7. #7
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 376
    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 376
    Points : 41 544
    Points
    41 544
    Par défaut
    Pour le cas général, je ne sais plus...
    Mais pour les champs de bits, je suis 100% sûr que ce n'est pas garanti par le standard C (je ne me prononcerai pas pour POSIX).
    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
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 626
    Points : 30 684
    Points
    30 684
    Par défaut
    Salut,

    Un byte= taille d'un char, *généralement*= un octet (8 bits)

    Il veut dire que dans la structure
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    struct mastruct
    {
        int entier;
        char bf1 : 4;
        char bf2 : 4;
        char bf3 : 2;
        char bf4 : 6;
    };
    rien ne dit que l'on trouvera, dans l'ordre, bf1,bf2,bf3 et bf4 en mémoire (donc en général).

    Par contre, ce qui sera sur, c'est que nous trouverons bien les 4 bits de bf1 l'un à coté de l'autre (et pour cause: c'est un champs de bits )

    Au final, selon l'endianness (le "boutisme"),avec le code
    tu peux tout aussi bien pointer sur un bit d'un des autres champs de bits, un bit de entier ou un des bits "inutilisé" à cause de l'alignement... Bref, n'importe où
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  9. #9
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par koala01 Voir le message
    Salut,

    Un byte= taille d'un char, *généralement*= un octet (8 bits)

    Il veut dire que dans la structure
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    struct mastruct
    {
        int entier;
        char bf1 : 4;
        char bf2 : 4;
        char bf3 : 2;
        char bf4 : 6;
    };
    rien ne dit que l'on trouvera, dans l'ordre, bf1,bf2,bf3 et bf4 en mémoire (donc en général).

    Par contre, ce qui sera sur, c'est que nous trouverons bien les 4 bits de bf1 l'un à coté de l'autre (et pour cause: c'est un champs de bits )

    Au final, selon l'endianness (le "boutisme"),avec le code
    tu peux tout aussi bien pointer sur un bit d'un des autres champs de bits, un bit de entier ou un des bits "inutilisé" à cause de l'alignement... Bref, n'importe où
    ok merci.
    Du coup cela va à l'encontre de l'alignement des variables non?

  10. #10
    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 : 40
    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
    Un byte = ... = un octet (8 bits)
    Apparemment un byte peut faire autre chose que 8 bits, donc attention dans ce genre de raccourcis.

  11. #11
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 626
    Points : 30 684
    Points
    30 684
    Par défaut
    Citation Envoyé par Laurent Gomila Voir le message
    Apparemment un byte peut faire autre chose que 8 bits, donc attention dans ce genre de raccourcis.
    C'est pour cela que j'ai mis le généralement

    Mais évidemment, si ce terme si important n'apparait pas, ta réaction est justifiée
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  12. #12
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    merci

  13. #13
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 626
    Points : 30 684
    Points
    30 684
    Par défaut
    Citation Envoyé par Mongaulois Voir le message
    ok merci.
    Du coup cela va à l'encontre de l'alignement des variables non?
    Non, parce que tu as les trois "boutismes" qui entre en jeu

    Si l'on considère qu'un int fait 4 bytes et qu'un byte fait un octet, et selon le "boutisme" utilisé, tu peux avoir le bit de poids fort (celui qui a la plus grosse valeur) à trois endroit différent
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
         B31     B23     B15      B7    B0
          |       |       |       |      |
          ********************************
          ^               ^              ^
        ici              ici            ici
    ("big-endian")       |        ("little-endian")
               ("middle-endian")
    (middle-endian est peut etre mal placé )

    Tu aura toujous tes 4 séries de 8 bits, mais leur valeur "réelle" sera différente (la valeur 255 (11111111 en binaire) peut se retrouver entre B0 et B7, ou entre B24 et B31, ou entre B8 et B15 (ou est-ce entre B16 et B23 ... je sais jamais comment s'organise le "middle-endian" )

    L'alignement des données aura pour but de s'assurer que, quoi qu'il en soit (et selon l'exemple), un int commencera systématiquement à une adresse mémoire "multiple de 32".

    Cela signifie que, si tu a 16 bits utilisés, les 16 qui ne le sont pas, et selon le boutisme, peuvent être:
    • les 16 à gauche,
    • les 16 à droite ou,
    • pourquoi pas, 8 de chaque coté


    Cela signifie aussi que, selon le boutisme et la position de ton champs de bits, si tu sort de ton champs de bits, tu peux tres bien te retrouver
    • dans le champs de bits qui se trouve à coté
    • dans la parte "inutilisée" due à l'alignement
    • carrément dans un autre "champs 32 bits"


    Les explications ne sont pas tout à fait justes, mais l'idée générale y est
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  14. #14
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    D'après ce que tu me dit avec les champs de bits, les variable déclaré avec, vont être mis cote à cote en mémoire, dans un ordre indéfini( par rapport a l'endian) ou il n' aura pas d'alignement, puis les autre variable seront aligné par le compilateur. C'est bien ça?

  15. #15
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 626
    Points : 30 684
    Points
    30 684
    Par défaut
    C'est à peu pres cela.

    Le fait est que, si tu as plusieurs variables qui peuvent entrer dans un entier (char, short), elles seront regroupées dans un entier, mais que, dés que le compilateur devra placer un entier, il sera automatiquement placé de manière à ce commencer à une adresse multiple de 32. (toujours selon l'exemple précédent)

    Pour te permettre de comprendre, le code
    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
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
     
    #include <iostream>
    using namespace std;
    struct str1
    {
        char ch1;
        char ch2;
        char ch3;
        char ch4;
        int entier;
    };
    struct str2
    {
        char ch1;
        char ch2;
        int entier;
        char ch3;
        char ch4;
    };
    int main()
    {
        cout<<"taille d'un char = "<<sizeof(char) <<endl
            <<"taille d'un entier = "<<sizeof(int) <<endl
            <<"    4 char + 1 int ="<<sizeof(int)+sizeof(char)*4<<endl
            <<"taille de str1 = "<<sizeof(str1) <<endl
            <<"taille de str2 = "<<sizeof(str2) <<endl;
        return 0;
    }
    me donne la sortie
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    taille d'un char = 1
    taille d'un entier = 4
        4 char + 1 int = 8
    taille de str1 = 8
    taille de str2 = 12
    (une autre implémentation pourra donner d'autres valeurs )

    Le cas "peau de bananes" est donc celui d'une structure du genre de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    struct mastruct
    {
        char bf1 : 4;
        char bf2 : 4;
        int entier;
        char bf3 : 2;
        char bf4 : 6;
    };
    où, selon le compilateur utilisé, tu risque fort de te retrouver avec un structure prenant la taille de trois entiers, avec bf1 et bf2 se trouvant "cote à cote", et laissant 24 bits inutilisés (alignement sur les 32 d'un entier), l'entier juste à coté, et les champs de bits bf3 et bf4 se trouveront "cote à cote" dans l'espace mémoire d'un troisième entier
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  16. #16
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    du coup
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    struct mastruct
    {
        char bf1 : 8;
        char bf2 : 8;
        int entier : 32;
        char bf3 : 8;
        char bf4 : 8;
    };
    mettra bien, dans l'ordre de endian ,
    char | char | int | char | char

    et il n'y aura donc pas eu d'alignement.

  17. #17
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 626
    Points : 30 684
    Points
    30 684
    Par défaut
    Le meilleur moyen de le savoir est encore de demander la taille de ta structure, mais tu risque fort de te retrouver avec un
    16bits inutilisés | char | char | int (début aligné en mémoire)| 16 bits inutilisés |char | char, ce qui montrerait que tu as eu un alignement (c'est le cas chez moi)

    Pour info... j'avais fais une erreur de recopie sur la sortie du code

    [EDIT]évidemment, la place des bits inutilisés dépendra de l'endianness
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  18. #18
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 626
    Points : 30 684
    Points
    30 684
    Par défaut
    Par contre, je viens de faire l'essai, avec deux structures du genre de
    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
    struct str
    {
        char ch1:8;
        char ch2:8;
        int entier:16;
        char ch3:8;
        char ch4:8;
    };
    struct str2
    {
        char ch1:8;
        char ch2:8;
        int entier:24;
        char ch3:8;
        char ch4:8;
    };
    Pour la première, j'obtiens une taille correspondant à 2 entiers, ce qui est logique, étant donné que 8+8+16=32

    Pour la deuxième, j'obtiens une taille correspondant à ... 3 entiers, ce qui semble indiquer que le compilateur s'est rendu compte qu'il ne savait pas faire entrer entier ni dans l'espace restant à coté de ch1+ch2 ni dans l'espace restant aux côtés de ch3+ch4

    Par contre, si on modifie l'ordre de déclaration des membres sous la forme de
    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
    struct str2
    {
        char ch1:8;
        char ch2:8;
        char ch3:8;
        char ch4:8;
        int entier:24;
    };
    /* OU */
    {
        char ch1:8;
        char ch2:8;
        char ch3:8;
        int entier:24;
        char ch4:8;
    };
    on retombe à une taille équivalent à 2 entiers...

    Et là, on retombe sur un comportement clairement expliqué dans la norme, à savoir que les membres de structures complexes sont placés en mémoire dans l'ordre de leur déclarations
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

  19. #19
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    ok merci, je voie le truc
    du coup
    Code C++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    struct
    {
    char a :6;
    char b :6;
    char c :6;
    char d :6;
    char e :6;
    }
    avec un alignement de :
    - 8 fera 5 Byte : (6 +alignement_8) *5 = 40 bits car sur 8bits on ne peut pas mettre 2*6bits
    - 32 fera 4 Byte : 6*5 = 30 bits + 2 bits inutilisé car sur 32bits on peut mettre 5*6bits

  20. #20
    Expert éminent sénior
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 626
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 52
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 626
    Points : 30 684
    Points
    30 684
    Par défaut
    J'ai pas tout compris...

    Mais bon, retiens que la taille "de base" est le byte qui correspond *généralement* à celle d'un char (*typiquement* 8bits), et que tous les autres types primitifs s'alignent sur cette taille.

    La taille renvoyée par sizeof(untype) est la taille en bytes ( et donc, généralement à la taille d'un char).
    Chez moi:
    • char = 8bits -->sizeof(char)=1 (mais d'autres systèmes peuvent utiliser un nombre de bits différents
    • short=16 bits -->sizeof(short)=2
    • int= 32bits -->sizeof(int)=4
    • long= 32 bits -->sizeof(long)=4
    • long long=64 bits -->sizeof(long long)=8

    Il est à noter que c'est susceptible de changer d'une implémentation à l'autre, car la norme indique que:

    La taille d'un char doit au minimum avoir la taille pour représenter les caractères, et pour le reste que
    char=1<=short<=int<=long<=long long
    Il *me semble* aussi qu'elle indique qu'un entier () doit avoir une taille minimum suffisante pour représenter l'ensemble des adresses mémoire (donc, en gros, pour contenir un pointeur )

    Maintenant, il faut savoir qu'au niveau du processeur, on trouve ce que l'on appelle les ACU, qui sont souvent subdivisés en parties correspondant à un "byte" sur l'architecture donnée.

    Ainsi, sur mon "antique" athlon-xp 1800+, les acus sont composés que 4 parties de 8 bits (d'où l'architecture "32 bits" du processeur )

    et que les processeurs préfèrent, à choisir, travailler sur des acu pleins que sur une (ou plusieurs) partie(s) de leur acu.

    Comme la taille d'un acu permet, justement, de représenter toutes les adresses mémoires supportées par le processeur, on peut dire que la taille d'un acu est celle d'un int

    C'est la raison pour laquelle on s'aperçoit souvent qu'il y a alignement des données (un char ou un short sera bien souvent "promu" au rang d'entier)
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [Pentium] Optimisation - Alignement
    Par Blustuff dans le forum Assembleur
    Réponses: 58
    Dernier message: 05/04/2003, 17h01
  2. JBuilder7 & JTable Colonne alignement
    Par Tonton Luc dans le forum JBuilder
    Réponses: 5
    Dernier message: 06/11/2002, 17h32
  3. [Datareport] Alignement
    Par SpaceFrog dans le forum VB 6 et antérieur
    Réponses: 2
    Dernier message: 05/11/2002, 11h53
  4. [VB6] [Printer] Chiffres alignés à droite
    Par Laye dans le forum VB 6 et antérieur
    Réponses: 7
    Dernier message: 03/10/2002, 18h36
  5. Problème avec [b]struct[/b]
    Par Bouziane Abderraouf dans le forum CORBA
    Réponses: 2
    Dernier message: 17/07/2002, 10h25

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