¿Es válido usar campos de bits con unión?

He usado un campo de bits con una estructura como esta,

struct
{
       unsigned int is_static: 1;
       unsigned int is_extern: 1;
       unsigned int is_auto: 1;
} flags;

Ahora me preguntaba si esto se puede hacer con una unión, así que modifiqué el código como,

union
{
       unsigned int is_static: 1;
       unsigned int is_extern: 1;
       unsigned int is_auto: 1;
} flags;

Encontré el campo de bits con trabajos de unión, pero todos esos campos en la unión se asignan a un solo bit, como entendí por la salida. Ahora veo que no es erróneo usar campos de bits con unión, pero me parece que usarlo así no es operacionalmente correcto. Entonces, ¿cuál es la respuesta? ¿Es válido usar un campo de bits con unión?

preguntado el 04 de julio de 12 a las 10:07

Por favor, ¿qué no funciona correctamente? -

3 Respuestas

Es válido pero, como descubrió, no es útil de la forma en que lo hizo allí.

Puede hacer algo como esto para poder restablecer todos los bits al mismo tiempo usando banderas.

union {
    struct {
        unsigned int is_static: 1;
        unsigned int is_extern: 1;
        unsigned int is_auto: 1;
    };
    unsigned int flags;
};

O podrías hacer algo como esto:

union {
    struct {
        unsigned int is_static: 1;
        unsigned int is_extern: 1;
        unsigned int is_auto: 1;
    };
    struct {
        unsigned int is_ready: 1;
        unsigned int is_done: 1;
        unsigned int is_waiting: 1;
    };
};

Respondido 04 Jul 12, 11:07

He agregado algunos puntos y comas asumiendo que desea estructuras anónimas. También tenga en cuenta que no son C estándar. En gcc, debe usar -fms-extensions para que estos funcionen. - unkulunkulu

Te dan un arma y balas. ¿Está bien pegarse un tiro en el pie con él? Por supuesto que no, pero nadie puede impedir que hagas esto si así lo deseas.

Mi punto es que, al igual que las pistolas y las balas, los campos de unión y de bits son herramientas y tienen su propósito, usos y "abusos". Entonces, usar campos de bits en unión, como ha escrito anteriormente, es C perfectamente válido pero una pieza de código inútil. Todos los campos dentro de la unión comparten la misma memoria, por lo que todos los campos de bits que menciona son esencialmente la misma bandera, ya que comparten la misma memoria.

respondido 01 mar '16, 11:03

Esta metáfora es mucho más inútil que el código en la pregunta del OP. - dan bechard

Muy útil si los bits pueden significar diferentes cosas en diferentes momentos, como es el caso de los registros de hardware en los microcontroladores. Esto también se puede encontrar con frecuencia en formatos de archivo como una forma de ahorrar espacio al agrupar diferentes tipos de datos en una matriz y tener una bandera que indique el tipo de cada elemento. SO realmente tiene un problema con las personas que piensan que saben todo acerca de cómo se debe usar la característica del idioma, en función de su experiencia personal limitada. - TrisT

Aquí hay un ejemplo de cómo usar campos de bits con uniones. También estoy mostrando cómo hacer arreglos para MSB. En imágenes se vería algo así:

 MSB        LSB
 7            0
+------+-------+
| five | three |
| bits | bits  |
+------+-------+

// A struct tag definition of 
// two bit fields in an 8-bit register
struct fields_tag {
   // LSB
   unsigned int five:5;
   unsigned int three:3;
   // MSB
};

// here is a tag and typedef for less typing
// to modify the 8-bit value as a whole
// and read in parts.
typedef union some_reg_tag {
    uint8_t raw;
    struct fields_tag fields;
} some_reg_t;

Aquí se explica cómo usar los campos de bits con Arduino

some_reg_t a_register;
a_register.raw = 0xC2;  // assign using raw field.

Serial.print("some reg = ");  // dump entire register
Serial.println(a_register.raw, HEX);   // dump register by field
Serial.print("some reg.three = ");
Serial.println(a_register.fields.three, HEX);
Serial.print("some reg.five = ");
Serial.println(a_register.fields.five, HEX);

Aquí está la salida que muestra los resultados.

some reg = C2
some reg.three = 6
some reg.five = 2

Respondido 04 Oct 21, 18:10

<a href='stackoverflow.com/users/5352316/trist'>TrisT> Háblame de eso. Alguien acaba de rechazar mi respuesta aquí mostrando al OP cómo hacer exactamente eso. Tengo que amar SO. - netskink

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.