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

Autres éditeurs Discussion :

Problème avec sizeof(...) : erreur de taille


Sujet :

Autres éditeurs

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Invité
    Invité(e)
    Par défaut Problème avec sizeof(...) : erreur de taille
    Bonjour,

    Je viens de découvrir une petite curiosité avec DevCpp, mais que j'ai reproduit aussi avec Builder C++...

    J'ai les structures suivante :
    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
    #include <windows.h>
     
    typedef struct _PlaceableMetaHeader{
      DWORD Key;           /* Magic number (always 9AC6CDD7h) */
      WORD  Handle;        /* Metafile HANDLE number (always 0) */
      WORD  Left;          /* Left coordinate in metafile units */
      WORD  Top;           /* Top coordinate in metafile units */
      WORD  Right;         /* Right coordinate in metafile units */
      WORD  Bottom;        /* Bottom coordinate in metafile units */
      WORD  Inch;          /* Number of metafile units per inch */
      DWORD Reserved;      /* Reserved (always 0) */
      WORD  Checksum;      /* Checksum value for previous 10 WORDs */
    } PLACEABLEMETAHEADER;
     
    typedef struct _WindowsMetaHeader {
      WORD  FileType;       /* Type of metafile (0=memory, 1=disk) */
      WORD  HeaderSize;     /* Size of header in WORDS (always 9) */
      WORD  Version;        /* Version of Microsoft Windows used */
      DWORD FileSize;       /* Total size of the metafile in WORDs */
      WORD  NumOfObjects;   /* Number of objects in the file */
      DWORD MaxRecordSize;  /* The size of largest record in WORDs */
      WORD  NumOfParams;    /* Not Used (always 0) */
    } WMFHEAD;
    Et le code suivant me renvoie des tailles de 24 octets...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    PLACEABLEMETAHEADER stHeader1;
    int nTaille = sizeof(stHeader1);// renvoie 24 au lieu de 22
     
    WMFHEAD stHeader2;
    nTaille = sizeof(stHeader2);// renvoie 24 au lieu de 18
    ... au lieu de 22 et 18...

    J'ai réussi à contourner le problème mais visiblement le sizeof arrondit la taille au multiple de 8 supérieur.

    Bon je viens de trouver la solution avec C++ Builder, c'est dans les options de compilation.
    Il faut aller dans "Projet \ Options \ Options avancées du compilateur \ Alignement des données : "byte" au lieu de "quad word" (par défaut) "

    Vous savez comment changer cette option avec DevCpp ?

  2. #2
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 42
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Par défaut
    Citation Envoyé par Kaji
    Vous savez comment changer cette option avec DevCpp ?
    C'est de gcc qu'il faut te préoccuper.

    C'est effectivement une question alignement des champs de la structure (une histoire d'optimisation), pour éviter cela, il faut déclarer la structure aunsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct foo
    {
      int x;
      char a, b, c, d;
    } __attribute__((packed));
    Hélas c'est spécifique à gcc

  3. #3
    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 : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Il me semble que sous Windows, les compilos fournissent des en-têtes du genre <pack8.h>, <pack16.h>, ... pour remplacer les commandes préprocesseur spécifiques à chaque compilo. Ca permettrait d'être déjà un peu plus portable.

  4. #4
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 43
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Par défaut
    Avec Visual, ça se modifie à l'aide des pragma. Mais dans un souci d'efficacité, ce n'est pas à recommander.

  5. #5
    Membre émérite
    Avatar de D[r]eadLock
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    504
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 504
    Par défaut
    Avec gcc, il y a l'option -fpack-struct pour "packer" les structures. C'est plus pratique que de changer tous les typedef struct avec __attribute__.

    Exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include <stdio.h>
     
    typedef struct {
        char   c;
        int    i;
        char   c2;
        double d;
    } structure;
     
    int main(void) {
        printf("Sizeof(structure)=%d\n",sizeof(structure));
        return 0;
    }
    Citation Envoyé par gcc -Wall -o align align.c && ./align
    Sizeof(structure)=20
    Citation Envoyé par gcc -Wall -fpack-struct -o align align.c && ./align
    Sizeof(structure)=14
    Quelqu'on connait-il un site qui donne les équivalents des options de compilations pour différents compilateurs ? (un peu comme http://predef.sourceforge.net qui donne les macros définis pour différentes plateforme (compilo/OS...)

    Rq: si tu n'as que deux structures qui doivent être "packées" l'__attribute__ est surement meilleur. Tu peux eventuellement te faire des macros pour choisir les modificateurs propres aux compilos avec le site ci-dessus, genre:
    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
    #ifdef __GNUC__
    #   define PackedStructHeader
    #   define PackedStructTrailer __attribute__((packed))
    #else
    #   ifdef _MSC_VER
    #   define PackedStructHeader  __declspec(align(8)) 
    #   define PackedStructTrailer
    #   endif
    #endif
    typedef PackedStructHeader struct {
        char   c;
        int    i;
        char   c2;
        double d;
    } PackedStructTrailer structure;
    Bon d'accord c'est un peu dégeu parce que gcc mets les options a la fin alors que Visual les met avant

    Rq: tu peux changer le titre du post qui n'est pas "erreur" avec sizeof mais "forcer des structures packées (ou packed ou paquées ??)

Discussions similaires

  1. Problème avec une erreur de type [DCC Erreur]
    Par colorid dans le forum Langage
    Réponses: 5
    Dernier message: 24/09/2007, 20h04
  2. [vba] Problème avec MoveNext - Erreur de collection ?
    Par ancel17 dans le forum VBA Access
    Réponses: 6
    Dernier message: 07/05/2007, 17h17
  3. problème avec sizeof
    Par PIL dans le forum C
    Réponses: 10
    Dernier message: 10/09/2006, 12h12
  4. Problème avec une erreur d'exception inconnue
    Par yoyo72 dans le forum Delphi
    Réponses: 5
    Dernier message: 09/08/2006, 11h52
  5. Problème avec l'erreur 3464 sur access
    Par somalien10 dans le forum Access
    Réponses: 10
    Dernier message: 16/05/2006, 09h30

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