2010-11-30 12 views
10

Tengo una estructura de campos de bits que suman 48 bits. En GCC, esto da como resultado correctamente una estructura de 6 bytes, pero en MSVC la estructura tiene 8 bytes. Necesito encontrar la manera de obligar a MSVC a empaquetar la estructura de forma adecuada, tanto para la interoperabilidad como para su uso en un entorno de memoria crítica.Forzar empaque de campo de bit no alineado en MSVC

La estructura que se muestra a continuación consta de tres números de 15 bits, un número de 2 bits y un signo de 1 bit. 15 + 15 + 15 + 2 + 1 = 48, así que en teoría debería caber en seis bytes, ¿verdad?

struct S 
{ 
    unsigned short a:15; 
    unsigned short b:15; 
    unsigned short c:15; 
    unsigned short d:2; 
    unsigned short e:1;  
}; 

Sin embargo, la compilación de esto en ambos CCG y MSVC resultados en sizeof(S) == 8. Pensando que esto podría tener que ver con la alineación, traté de usar #pragma pack(1) antes de la declaración struct, diciéndole al compilador que vuelva a los límites de byte, no int,. En GCC, this worked, lo que resulta en sizeof(S) == 6.

Sin embargo, en MSVC05, el tamaño aún salió a 8, incluso con pack(1) conjunto! Después de leer this other SO answer, intenté reemplazar unsigned short d con unsigned char y unsigned short e con bool. El resultado es sizeof(S) == !

Encontré que si dividía d en dos campos de un bit y los colocaba entre los otros miembros, la estructura finalmente se empaquetaba correctamente.

struct S 
{ 
    unsigned short a:15; 
    unsigned short dHi : 1; 
    unsigned short b:15; 
    unsigned short dLo : 1; 
    unsigned short c:15; 
    unsigned short e:1;  
}; 

printf("%d\n", sizeof(S)); // "6" 

Pero tener d dividida como que es engorroso y causa problemas para mí más adelante, cuando tengo que trabajar en la estructura. ¿Hay alguna manera en que pueda forzar a MSVC a empaquetar esta estructura en 6 bytes, exactamente como lo hace GCC?

Respuesta

5

Es la implementación definida cómo se colocarán los campos en la estructura. Visual Studio colocará campos de bit consecutivos en un tipo subyacente, si puede, y desperdiciará el espacio sobrante. (C++ Bit Fields in VS)

+0

Gracias por la referencia, eso es bueno saberlo. – Crashworks

+0

Excelente referencia! Me ayudó con mi problema (VC++ siguió haciendo que mi bitfield de 16 bits se convirtiera en una estructura de 4 bytes ... ahora sé por qué – nirbruner

0

No lo creo, y creo que es el comportamiento de MSVC lo que en realidad es correcto y GCC que se desvía del estándar.

AFAIK, el estándar no permite que los campos de bit crucen los límites de palabras del tipo subyacente.

+3

De 9.6.1/"Nota: Los campos de bits straddle unidades de asignación en algunas máquinas y no en otros." –

3

Si utiliza el tipo "unsigned __int64" para declarar todos los elementos de la estructura, obtendrá un objeto con sizeof (S) = 8, pero los dos últimos bytes no se utilizarán y los primeros seis contendrá los datos en el formato que desee.

Alternativamente, si se puede aceptar alguna estructura reordenación, esto funcionará

#pragma pack(1) 
struct S3 
{ 
    unsigned int a:15; 
    unsigned int b:15; 
    unsigned int d:2; 
    unsigned short c:15; 
    unsigned short e:1;  
}; 
Cuestiones relacionadas