Spécifier la taille du type enum en C

Déjà lu cette question liée , mais cherchait quelque chose d’un peu plus spécifique.

  • Existe-t-il un moyen de dire à votre compilateur quelle est la largeur de votre enum?
  • Si oui, comment faites-vous? Je sais comment le spécifier en C #; est-ce pareil fait en C?
  • Cela vaudrait-il la peine d’être fait? Quand la valeur enum est passée à une fonction, sera-t-elle passée comme une valeur int -size indépendamment de?

    Existe-t-il un moyen d’indiquer à votre compilateur quelle est la largeur souhaitée de votre enum?

    Dans le cas général non. Pas en standard C.

    Cela vaudrait-il la peine d’être fait?

    Ça dépend du contexte. Si vous parlez de passer des parameters à des fonctions, alors non, cela ne vaut pas la peine d’être fait (voir ci-dessous). S’il s’agit d’économiser de la mémoire lors de la construction d’agrégats à partir de types enum, cela peut valoir la peine d’être fait. Cependant, en C, vous pouvez simplement utiliser un type entier de taille appropriée au lieu du type enum dans les agrégats. En C (par opposition à C ++), les types enum et les types entiers sont presque toujours interchangeables.

    Quand la valeur enum est passée à une fonction, sera-t-elle passée en tant que valeur de taille int indépendamment?

    De nombreux compilateurs (la plupart) de nos jours transmettent tous les parameters en tant que valeurs de la taille naturelle des mots pour la plate-forme matérielle donnée. Par exemple, sur une plate-forme 64 bits, de nombreux compilateurs transmettent tous les parameters sous forme de valeurs 64 bits, quelle que soit leur taille réelle, même si type int a 32 bits sur cette plate-forme (donc, il n’est généralement pas passé sous la forme “int”.) -sized “valeur sur une telle plate-forme). Pour cette raison, il n’a aucun sens d’essayer d’optimiser les tailles d’énum pour le passage de parameters.

    Je crois qu’il y a un drapeau si vous utilisez GCC.

    -fshort-enums

    Vous pouvez le forcer à avoir au moins une certaine taille en définissant une valeur appropriée. Par exemple, si vous voulez que votre enum soit stocké avec la même taille qu’un int , même si toutes les valeurs tiennent dans un caractère, vous pouvez faire quelque chose comme ça:

     typedef enum { firstValue = 1, secondValue = 2, Internal_ForceMyEnumIntSize = MAX_INT } MyEnum; 

    Notez cependant que le comportement peut dépendre de l’implémentation.

    Comme vous le constatez, le fait de transmettre une telle valeur à une fonction entraînera son extension à un entier, mais si vous utilisez votre type dans un tableau ou une structure, la taille importera. Si vous vous souciez vraiment de la taille des éléments, vous devriez vraiment utiliser des types tels que int8_t , int32_t , etc.

    Il y a aussi un autre moyen si l’énum fait partie d’une structure:

     struct something { :0; enum whatever field:CHAR_BIT; :0; }; 

    Le: 0; peut être omis si le champ enum est entouré de champs normaux. S’il y a un autre champ de bits avant, le: 0 forcera l’alignement d’octet sur l’octet suivant pour le champ qui le suit.

    Cela dépend des valeurs assignées pour les enums.

    Ex: si la valeur supérieure à 2 ^ 32-1 est stockée, la taille allouée pour l’énumération globale passera à la taille suivante.

    Stockez la valeur 0xFFFFFFFFFFFF dans une variable enum, elle vous avertira si vous tentez de comstackr dans un environnement 32 bits (avertissement arrondi) où, comme dans une compilation de 64 bits, elle réussira et la taille allouée sera de 8 octets.

    Une autre méthode consiste à lancer l’énumération à l’intérieur d’un syndicat comme suit:

     union char_size { char a; enum { a = 1, b = 2, } val; }; 

    Cela forcerait le compilateur à insérer l’énum dans un caractère.