Champ de bits de manipulation en C

Le problème classique de test et de configuration de bits en un nombre entier dans C est peut-être le plus commun de niveau intermédiaire compétences en programmation. Vous jeu et le tester avec de simples masques de bits comme

unsigned int mask = 1<<11;

if (value & mask) {....} //Test for the bit
value |= mask;    //set the bit
value &= ~mask;   //clear the bit

Un intéressant post de blog soutient que c'est source d'erreurs, difficile à maintenir, et des mauvaises pratiques. Le langage C fournit elle-même peu d'accès au niveau de ce qui est typesafe et portable:

typedef unsigned int boolean_t;
#define FALSE 0
#define TRUE !FALSE
typedef union {
        struct {
                boolean_t user:1;
                boolean_t zero:1;
                boolean_t force:1;
                int :28;                /* unused */
                boolean_t compat:1;     /* bit 31 */
        };
        int raw;
} flags_t;

int
create_object(flags_t flags)
{
        boolean_t is_compat = flags.compat;

        if (is_compat)
                flags.force = FALSE;

        if (flags.force) {
                [...]
        }
        [...]
}

Mais cela me fait grincer des dents.

L'argument intéressant ma collègue de travail et j'ai eu à ce sujet est encore en suspens. Les deux styles de travail, et je maintiens le classique masque méthode est facile, sûr et clair. Mon collègue est d'accord, il est courant et facile, mais le champ de bits de l'union méthode vaut le supplément de quelques lignes pour le rendre portable et plus sûr.

Est-il des arguments en plus pour chaque côté? En particulier est-il un échec possible, peut-être avec l'endianness, que le masque de bits méthode peut manquer, mais où la structure de la méthode est sans danger?

  • Je pense que vous avez droit à grincer des dents.
  • Comment flags.compat et flags.force travail? Ne devraient-ils pas être flags.{structure_name}.compat et flags.{structure_name}.force?
  • vous pouvez vous référer à la membres non struct/union directement dans gcc GNU extension, et il est maintenant en C11 standard.
InformationsquelleAutor SPWorley | 2009-06-25