2010-12-28 10 views
11

Estoy escribiendo una aplicación C++ para Windows XP/Vista/7 usando Visual Studio 2008. Algunas de mis estructuras usan un campo de bit, como se muestra en el ejemplo.¿Qué extremo de un campo de bit es el bit más significativo?

typedef struct myStruct_tag 
{ 
    BYTE myVar1; 
    WORD myVar2; 
    WORD myVar3; 
    union 
    { 
     struct 
     { 
      BYTE   :1; 
      BYTE field1 :1; 
      BYTE field2 :1; 
      BYTE reserved :5; 
     } myBitField; 
     BYTE myVar4; 
    }; 
    BYTE myVar5; 
    BYTE myVar6; 
} myStruct_t; 

¿Cuál final del campo es el bit más significativo?

+2

Nota: De acuerdo con la norma, el MSB no está definido. En su plataforma específica, sospecho que 'reserved' contiene el MSB pero no estoy seguro. –

+0

@Billy: Parece una respuesta para mí. –

+0

Er ... Esa es una pregunta bastante extraña. Solo tiene 3 campos de bit en su declaración. 2 de ellos son campos de bits de 1 bit, es decir, no hay problema de "qué final" con ellos, ya que solo hay 1 bit allí. El único campo de bits de múltiples bits llamado 'reserved', que sugiere que no se usa en absoluto. Entonces, básicamente, el único campo de bits al que puede aplicar la pregunta es 'reservado'. ¿Estás preguntando sobre 'reservado' específicamente? Si no, aclara tu pregunta. – AnT

Respuesta

18

C99 estándar 6.7.2.1/10 (el énfasis es mío):

Una implementación puede asignar cualquier unidad de almacenamiento direccionable lo suficientemente grande como para contener un campo de bits. Si queda suficiente espacio, un campo de bits que sigue inmediatamente a otro campo de bits en una estructura debe empaquetarse en los bits adyacentes de la misma unidad. Si queda espacio insuficiente, si un campo de bits que no encaja se coloca en la siguiente unidad o se solapa con las unidades adyacentes, se define la implementación. El orden de asignación de los campos de bits dentro de una unidad (de orden alto a orden bajo o de orden bajo a orden superior) está definido por la implementación. La alineación de la unidad de almacenamiento direccionable no está especificada.

Por lo tanto, el orden debe ser documentado por la implementación de su compilador.

Sin embargo, tanto acerca de cómo se implementan los campos de bits se ha definido o no la especificación de que usarlos para modelar hardware, protocolo de conexión o campos de formato de archivo de forma portátil no vale la pena intentarlo.

Si desea que sus 'campos de bits' para modelar algo externo a su programa (como las cosas de arriba), usan máscaras explícitos, el escenario y la limpieza de los bits mediante los operadores estándar bit a bit (|, '& , ~ , < < `, etc.). Use funciones auxiliares en línea (o incluso macros si es necesario) para hacer esto más fácil/más claro en su código.

+2

+10 si pudiera. Su respuesta a esta pregunta es la mejor razón para no utilizar bitfields para lo principal para lo que la gente cree que es útil. –

+0

No me di cuenta de que la gente intenta usarlos de manera portátil, el único uso que he visto es "hablar con el hardware de mi programa que usa el compilador X". Y mira todos los tropecientos de "Yo hago esto en el compilador X, ¿cómo hago eso en el compilador Y"? –

+0

@CodeAbominator: como ejemplo, he visto campos de bits utilizados para descifrar mensajes de protocolo de red o formatos de archivo binarios. También he visto que parte de ese código no funciona cuando se compila para una plataforma diferente. –

2

Si está preguntando qué bits en myBitField están almacenados en qué bits del byte en la memoria, eso está explícitamente indefinido por los estándares de C. Tendrás que aprender por experimentación. Probablemente valga la pena, si está haciendo algo cuando esto realmente importa, utilizar un enfoque en el que # defina field1 como un valor hexadecimal (por ejemplo, 0x40 o 0x02) y colóquelo donde lo desee.

+0

Desafortunadamente, las pruebas funcionales de esta parte del código duran al menos semanas, si no meses. (Hay que escribir mucho para probarlo realmente porque ahora estoy en un punto en el que todo lo que queda por escribir depende más o menos de todo lo demás.) Las constantes definidas son una opción, pero preferiría para usar campos de bits porque el primero requeriría * lot * más lógica en mi código. –

+1

Bueno, un experimento rápido debería mostrarle lo que el compilador está haciendo ahora ... simplemente defina la unión como arriba, asigne 0 a 'myVar4', luego asigne 1 a' campo1' e imprima el valor resultante de 'myVar4'. Sin embargo, me gustaría colgar un nombre en el bit no utilizado que has definido antes de 'field1', para que el compilador no lo optimice. – jmaynard

4

el estudio de 2008 documentos visuales compilador indican:

El orden de los datos declarados como campos de bits es de bajo a alto poco

De "C++ Bit Fields", MSDN C++ Language Reference, Visual Studio 2008 version

+0

Como otros han notado, las normas relevantes no especifican esto, y es agradable escribir código que cumpla con los estándares, pero esta es la respuesta a la pregunta que se hizo, y el lector puede decidir si quiere usar sus poderes para siempre. o por increíble ;PAG – rakslice

Cuestiones relacionadas