¿Qué significan dos puntos en una declaración de estructura, como :1, :7, :16 o :32?

Resuelto derrdji asked hace 14 años • 3 respuestas

¿Qué significa el siguiente código C++?

unsigned char a : 1; 
unsigned char b : 7;

Supongo que crea dos caracteres a y b, y ambos deberían tener un byte de longitud, pero no tengo idea de qué hace la parte ": 1" y ": 7".

derrdji avatar Oct 22 '09 11:10 derrdji
Aceptado

El 1 y el 7 son tamaños de bits para limitar el rango de valores. Por lo general, se encuentran en estructuras y uniones. Por ejemplo, en algunos sistemas (depende del charancho y las reglas de embalaje, etc.), el código:

typedef struct {
    unsigned char a : 1;
    unsigned char b : 7;
} tOneAndSevenBits;

crea un valor de 8 bits, un bit para ay 7 bits para b.

Normalmente se utiliza en C para acceder a valores "comprimidos", como un nybble de 4 bits que podría estar contenido en la mitad superior de un carácter de 8 bits:

typedef struct {
    unsigned char leftFour  : 4;
    unsigned char rightFour : 4;
} tTwoNybbles;

Para los abogados de idiomas entre nosotros, la sección 9.6 del estándar C++11 explica esto en detalle, ligeramente parafraseado:


Campos de bits [class.bit]

Un miembro-declarador de la forma

     identificador opt    atributo-especificador opt    :    expresión-constante

especifica un campo de bits; su longitud está separada del nombre del campo de bits por dos puntos. El especificador de atributo opcional pertenece a la entidad que se declara. El atributo de campo de bits no forma parte del tipo de miembro de la clase.

La expresión-constante será una expresión constante integral con un valor mayor o igual a cero. El valor de la expresión constante integral puede ser mayor que el número de bits en la representación del objeto del tipo de campo de bits; en tales casos, los bits adicionales se utilizan como bits de relleno y no participan en la representación del valor del campo de bits.

La asignación de campos de bits dentro de un objeto de clase está definida por la implementación. La alineación de los campos de bits está definida por la implementación. Los campos de bits están empaquetados en alguna unidad de asignación direccionable.

Nota: los campos de bits abarcan unidades de asignación en algunas máquinas y no en otras. Los campos de bits se asignan de derecha a izquierda en algunas máquinas y de izquierda a derecha en otras. - nota final

paxdiablo avatar Oct 22 '2009 04:10 paxdiablo

Creo que esos serían campos de bits.

Azeem.Butt avatar Oct 22 '2009 04:10 Azeem.Butt

Estrictamente hablando, un campo de bits debe ser int, unsigned int o _Bool. Aunque la mayoría de los compiladores aceptarán cualquier tipo integral.

Referencia C11 6.7.2.1:

Un campo de bits deberá tener un tipo que sea una versión calificada o no calificada de _Bool, int con signo, int sin signo o algún otro tipo definido por la implementación.

Su compilador probablemente asignará 1 byte de almacenamiento, pero puede obtener más libremente.

Referencia C11 6.7.2.1:

Una implementación puede asignar cualquier unidad de almacenamiento direccionable lo suficientemente grande como para contener un campo de bits.

El ahorro se produce cuando se tienen varios campos de bits declarados uno tras otro. En este caso, el almacenamiento asignado se empaquetará si es posible.

Referencia C11 6.7.2.1:

Si queda suficiente espacio, un campo de bits que sigue inmediatamente a otro campo de bits en una estructura se empaquetará en bits adyacentes de la misma unidad. Si no queda suficiente espacio, la implementación define si un campo de bits que no encaja se coloca en la siguiente unidad o se superpone a unidades adyacentes.

evaitl avatar Jul 21 '2016 15:07 evaitl