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 :

Forcer le type d'un enum en C


Sujet :

C

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2016
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2016
    Messages : 8
    Points : 7
    Points
    7
    Par défaut Forcer le type d'un enum en C
    Bonjour,

    Pour une application où la taille des données est critique, j'essai de créer un type enum. Cependant, celui-ci possède toujours une taille de 4 octets (int), même lorsque qu'il y a peu d'identificateurs.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    enum Mon_type
    	{
    		A,B,C
    	};
    typedef enum Mon_type Mon_type;
    Est-il possible de le réduire la taille de celui-ci à seulement 2 (unsigned short) ou même 1 octet (char) ?

    Merci d'avance

    Quentin

  2. #2
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    La norme ne spécifie rien de la sorte mais je pense que les compilateurs implémentent tous quelque chose qui permette d'y remédier. De mémoire avec GCC c'est l'option --short-enums.

    Autrement, tu as toujours la possibilité de remplacer l'enum par un unsigned char et quelques macros (pas top, je sais).

    Questions bateau (premature optimization, tout ça) : est-ce si critique que cela ? As-tu déjà atteint les limites de ton implémentation actuelle ?

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2016
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2016
    Messages : 8
    Points : 7
    Points
    7
    Par défaut
    Merci de ta réponse.
    C'est aussi ce que j'ai pu voir, mais cela ne change apparemment pas sa taille (lorsque je la récupère avec sizeof()), je ne sais pas pourquoi.

    J'ai egalement essayé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    enum Mon_type : uint16_t
    	{
    		A,B,C
    	};
    Mais j'obtiens des erreurs de ce type :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    error: ISO C forbids forward references to ‘enum’ types [-Wpedantic]
      enum Mon_type : uint16_t
           ^
    error: expected identifier or(’ before ‘:’ token
      enum Mon_type : uint16_t
                   ^
    error: ISO C does not allow extra ‘;’ outside of a function [-Wpedantic]
    Oui, effectivement, j'aimerais que cela reste le plus clair possible.
    Oui, c'est critique. Probablement pas, mais j'essaye de récupérer des octets où cela est possible.

  4. #4
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Non mais n'essaie pas des trucs au pif, ça ne fonctionne pas en C.


    Citation Envoyé par quentino18 Voir le message
    C'est aussi ce que j'ai pu voir, mais cela ne change apparemment pas sa taille (lorsque je la récupère avec sizeof()), je ne sais pas pourquoi.
    En es-tu sûr ?

    Code enum.c : 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
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    #include <stdio.h>
     
    enum Enum0 {
        A, B, C
    };
     
    enum Enum1 {
        D = 0, E, F
    };
     
    enum Enum2 {
        G = 0xfd51f,
        H = 0x51a081,
        I = 42
    };
     
    enum Enum3 {
        J = 0,
        K = -128,
        L = 127
    };
     
    enum Enum4 {
        M,
        N,
        O,
        P = (int)-1
    };
     
    enum Enum5 {
        Q,
        R,
        S = 0xffff,
        T = 3
    };
     
    int main(int argc, char *argv[]) {
        printf(
            "sizeof(Enum0): %zu\n"
            "sizeof(Enum1): %zu\n"
            "sizeof(Enum2): %zu\n"
            "sizeof(Enum3): %zu\n"
            "sizeof(Enum4): %zu\n"
            "sizeof(Enum5): %zu\n",
            sizeof(enum Enum0), sizeof(enum Enum1),
            sizeof(enum Enum2), sizeof(enum Enum3),
            sizeof(enum Enum4), sizeof(enum Enum5)
        );
     
        return 0;
    }

    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
    $ gcc -std=c11 -pedantic -Wall enum.c
    $ ./a.out
    sizeof(Enum0): 4
    sizeof(Enum1): 4
    sizeof(Enum2): 4
    sizeof(Enum3): 4
    sizeof(Enum4): 4
    sizeof(Enum5): 4
    $ gcc -std=c11 -pedantic -Wall --short-enums enum.c
    $ ./a.out
    sizeof(Enum0): 1
    sizeof(Enum1): 1
    sizeof(Enum2): 4
    sizeof(Enum3): 1
    sizeof(Enum4): 1
    sizeof(Enum5): 2

    Citation Envoyé par quentino18 Voir le message
    Oui, c'est critique. Probablement pas, mais j'essaye de récupérer des octets où cela est possible.
    Donc pas vraiment. Commence par identifier les points de blocage pour ensuite y remédier.

    Et passer tes int en char ou short rend probablement ton programme moins performant, au moins sur architecture x86 32/64 bits.

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2016
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2016
    Messages : 8
    Points : 7
    Points
    7
    Par défaut
    AH oui, effectivement, cela marche quand on essai de récupérer la taille de cette enum seule.
    Cependant, si celle-ci fait partie d'une structure, elle fait 4 octets, en plus de rendre le programme moins performant, cela est donc sans interêt :-)

    Merci !

    Edit : Ah finalement, Il y a quelque chose qui change, la taille de la structure diminue effectivement.

  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
    Dans une structure, tu as probablement du padding. Peux-tu nous montrer un extrait de code reproduisant ton problème (en incluant la commande de compilation) ?

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2016
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2016
    Messages : 8
    Points : 7
    Points
    7
    Par défaut
    Autant pour moi, la taille change aussi dans la structure

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    struct Struct
    	{
    		Enum1 A; //1 octet avec (--short-enums) , 4 sinon
    		Enum2 B; //1 octet avec (--short-enums) , 4 sinon
    		Enum3 C; //1 octet avec (--short-enums) , 4 sinon
    		unsigned int a; //4 octets
    		unsigned short b; //2 octets
    		unsigned int c;  //4 octets
    		int* d; //8 octets
    		int* e //8 octets
    	};
    Donc un total de 29 octets avec (--short-enums), 38 sinon.
    C'est cohérent.

    Ce que je trouve bizarre c'est ce que me renvoi sizeof(Struct) :
    32 octets avec (--short-enums) et 40 octets sinon.

    Edit : Je vais pas mettre mon Makefile ici, mais en gros :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    gcc -Wall -pedantic-errors -Wextra --short-enums    -c -o stack.o stack.c
    gcc -Wall -pedantic-errors -Wextra --short-enums    -c -o idStack.o idStack.c
    gcc -Wall -pedantic-errors -Wextra --short-enums    -c -o main.o main.c
    gcc -o Prog main.o stack.o idStack.o

  8. #8
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Tu as un byte de padding après le membre C et deux après le membre b. Même en réorganisant tu ne peux pas faire mieux, ta structure hérite de l'alignement des int * (très probablement 8 bytes sur machine 64 bits).

  9. #9
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2016
    Messages
    8
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 29
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2016
    Messages : 8
    Points : 7
    Points
    7
    Par défaut
    D'accord,
    Donc autant utiliser un unsigned int au lieu du unsigned short si cela n'est pas plus imposant ...

  10. #10
    Membre averti Avatar de yetimothee
    Homme Profil pro
    Étudiant
    Inscrit en
    Mai 2007
    Messages
    260
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2007
    Messages : 260
    Points : 364
    Points
    364
    Par défaut
    Hello,
    regarde du coté de l'attribut "packed" de gcc : https://gcc.gnu.org/onlinedocs/gcc/C...ype-Attributes
    Le programme suivant :
    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
    29
    30
    31
    32
    33
     
    #include <stdio.h>
     
    enum __attribute__((packed)) packed_enum { 
        PACKED_FIELD_A,
        PACKED_FIELD_B,
    };
     
    enum unpacked_enum { 
        UNPACKED_FIELD_A,
        UNPACKED_FIELD_B,
    };
     
    struct __attribute__((packed)) packed_struct { 
        enum packed_enum e;
        short s;
    };
     
    struct unpacked_struct { 
        enum packed_enum e;
        short s;
    };
     
    int main(void) { 
        printf("packed enum size:       %zu\n"
               "unpacked enum size:     %zu\n"
               "packed struct size:     %zu\n"
               "unpacked struct size:   %zu\n",
               sizeof(enum packed_enum), sizeof(enum unpacked_enum),
               sizeof(struct packed_struct), sizeof(struct unpacked_struct));
     
        return 0;
    }
    va produire la sortie suivante :
    packed enum size: 1
    unpacked enum size: 4
    packed struct size: 3
    unpacked struct size: 4

Discussions similaires

  1. Forcer le type d'une colonne
    Par redabadache3 dans le forum Macros et VBA Excel
    Réponses: 8
    Dernier message: 11/09/2007, 06h35
  2. [DOM] [INPUT text] Forcer le type du champ
    Par Nicomart dans le forum Général JavaScript
    Réponses: 11
    Dernier message: 24/07/2007, 13h20
  3. Réponses: 4
    Dernier message: 23/12/2005, 19h35
  4. forcer la taille d'un enum
    Par tut dans le forum MFC
    Réponses: 5
    Dernier message: 29/09/2005, 15h49
  5. forcer un type
    Par lol_adele dans le forum Langage
    Réponses: 3
    Dernier message: 05/09/2005, 11h28

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