sirve - Obteniendo el tamaño de un campo individual de un campo struct C++
struct syntax (6)
Esto no es posible
Respuesta para comentar: como el tipo es solo un int, no hay un tipo ''bit''. La sintaxis de asignación de campo de bit es muy breve para realizar el código bit a bit para lecturas y escrituras.
La versión corta es: ¿Cómo aprendo el tamaño (en bits) de un campo individual de un campo de C ++?
Para aclarar, un ejemplo del campo del que estoy hablando:
struct Test {
unsigned field1 : 4; // takes up 4 bits
unsigned field2 : 8; // 8 bits
unsigned field3 : 1; // 1 bit
unsigned field4 : 3; // 3 bits
unsigned field5 : 16; // 16 more to make it a 32 bit struct
int normal_member; // normal struct variable member, 4 bytes on my system
};
Test t;
t.field1 = 1;
t.field2 = 5;
// etc.
Obtener el tamaño de todo el objeto Test es fácil, solo decimos
sizeof(Test); // returns 8, for 8 bytes total size
Podemos obtener un miembro de estructura normal a través de
sizeof(((Test*)0)->normal_member); // returns 4 (on my system)
Me gustaría saber cómo obtener el tamaño de un campo individual, digamos Test :: field4. El ejemplo anterior para un miembro de estructura normal no funciona. ¿Algunas ideas? ¿O alguien sabe una razón por la cual no puede funcionar? Estoy bastante convencido de que sizeof no será de ayuda ya que solo devuelve el tamaño en bytes, pero si alguien sabe lo contrario, soy todo oídos.
¡Gracias!
No creo que puedas hacerlo. Si realmente necesita el tamaño, le sugiero que use un #define
(o, mejor aún, si es posible una variable const
- no estoy seguro si eso es legal) como tal:
#define TEST_FIELD1_SIZE 4
struct Test {
unsigned field1 : TEST_FIELD1_SIZE;
...
}
No puede tomar el sizeof
un campo de bits y obtener el número de bits.
Su mejor opción sería utilizar #define
s o enum
s:
struct Test {
enum Sizes {
sizeof_field1 = 4,
sizeof_field2 = 8,
sizeof_field3 = 1,
sizeof_field4 = 3,
sizeof_field5 = 16,
};
unsigned field1 : sizeof_field1; // takes up 4 bits
unsigned field2 : sizeof_field2; // 8 bits
unsigned field3 : sizeof_field3; // 1 bit
unsigned field4 : sizeof_field4; // 3 bits
unsigned field5 : sizeof_field5; // 16 more to make it a 32 bit struct
int normal_member; // normal struct variable member, 4 bytes on my system
};
printf("%d/n", Test::sizeof_field1); // prints 4
En aras de la coherencia, creo que puede mover al normal_member
hasta la parte superior y agregar una entrada en Sizes
usando sizeof(normal_member)
. Sin embargo, esto ensucia con el orden de tus datos.
Parece poco probable, ya que sizeof () está en bytes y quieres bits.
http://en.wikipedia.org/wiki/Sizeof
basándose en la respuesta del conteo de bits, puede usar.
Puede calcular el tamaño en tiempo de ejecución, por ejemplo,
//instantiate
Test t;
//fill all bits in the field
t.field1 = ~0;
//extract to unsigned integer
unsigned int i = t.field1;
... TODO use contents of i to calculate the bit-width of the field ...
Usando la idea de ChrisW (bueno, por cierto), puedes crear una macro auxiliar:
#define SIZEOF_BITFIELD(class,member,out) { /
class tmp_; /
tmp_.member = ~0; /
unsigned int tmp2_ = tmp_.member; /
++tmp2_; /
out = log2(tmp2_); /
}
unsigned int log2(unsigned int x) {
// Overflow occured.
if(!x) {
return sizeof(unsigned int) * CHAR_BIT;
}
// Some bit twiddling... Exploiting the fact that floats use base 2 and store the exponent. Assumes 32-bit IEEE.
float f = (float)x;
return (*(unsigned int *)&f >> 23) - 0x7f;
}
Uso:
size_t size;
SIZEOF_BITFIELD(Test, field1, size); // Class of the field, field itself, output variable.
printf("%d/n", size); // Prints 4.
Mis intentos de usar funciones con plantilla han fallado. Sin embargo, no soy un experto en plantillas, por lo que aún es posible tener un método limpio (por ejemplo, sizeof_bitfield(Test::field1)
).