structs sirve que para array c++ struct field sizeof

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.



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) ).