2017-01-25 1 views
0

J'ai vu quelques questions ici sur la façon de forcer une énumération à 8 ou 16 bits. La réponse commune était que cela peut être fait en C++ 11 ou supérieur. Malheureusement, je n'ai pas ce luxe.Forçage champ enum à 8 bits en C standard avec champs de bits

Alors, voici ce que je pense. J'ai seulement besoin que l'enum soit de 8 bits quand c'est dans une structure dont je veux minimiser la taille. Alors:

Option A:

typedef enum { A, B, C, MAX = 0xFF } my_enum; 

struct my_compact_struct 
{ 
    my_enum field1 : 8; // Forcing field to be 8 bits 
    uint8_t something; 
    uint16_t something_else; 
}; 

Je pense que la plupart ou tous les optimiseurs devrait être assez intelligent pour gérer le 8 BitField efficacement.

Option B:

Ne pas utiliser un ENUM. Utilisez plutôt typedef et les constantes.

typedef uint8_t my_type; 

static const my_type A = 0; 
static const my_type B = 1; 
static const my_type C = 2; 

struct my_compact_struct 
{ 
    my_type field1; 
    uint8_t something; 
    uint16_t something_else; 
}; 

Option A est actuellement mis en œuvre et semble fonctionner, mais comme je veux faire (maintenant et dans l'avenir) ce qui est correct maintenant et pas seulement ce qui fonctionne, je me demandais si l'option B est nettement meilleure.

Merci,

+2

(A) ne minimisera pas le champ. Il ne fera que 8 bits de tout le champ utilisable. – StoryTeller

+1

C et C++ sont des langages différents. Lequel utilisez-vous? – Olaf

+0

Votre question indique "Standard C" mais vos tags incluent "C++". Lequel utilisez-vous? –

Répondre

4

Si vos valeurs spécifiques dans un enum rentre dans un type plus petit qu'un int, puis une implémentation C est libre de choisir le type sous-jacent de la enum être un type plus petit qu'un int (mais le type des constantes enum dans ce cas sera int). Mais il y a aucun moyen vous pouvez forcer un compilateur C à utiliser un type plus petit qu'un int. Donc, dans cet esprit et le fait qu'un int est d'au moins 16 bits, vous n'avez pas de chance.

Mais enum s dans C sont un peu plus que des aides au débogage. Il suffit d'utiliser un type uint8_t si vous le compilateur, il a:

static const uint8_t something = /*some value*/ 

Sinon, utilisez un char et espoir que CHAR_BIT est 8.

+0

L'implémentation est libre de choisir un type plus petit pour un 'enum'. Mais les constantes sont ** toujours ** 'int'. Et 'const' ne qualifie pas une constante. C n'a pas de constantes symboliques autres que 'enum-constants' (qui sont en effet presque inutiles si vous avez besoin d'un autre type que' int') – Olaf

+0

@Olaf: Rappelez-moi de ne jamais vous prendre le parti adverse dans un quiz pub. – Bathsheba

+0

Intéressant ... un ancien patron à moi a dit quelque chose de très similaire :-) – Olaf

2

Option B serait préférable. Vous définissez le type en question comme étant de taille connue et les valeurs const que vous définissez auront également la taille correcte.

Alors que vous perdriez sur la numérotation implicite d'un enum, le dimensionnement explicite du champ et de ses valeurs le compense.

+3

Les valeurs 'const' ne sont pas des constantes, cependant. Un 'enum' pour les constantes ou' # define's sont meilleurs. (Je recommande ce dernier, car vous pouvez spécifier le type). – Olaf