¿Qué significan dos puntos en una declaración de estructura, como :1, :7, :16 o :32?
¿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".
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 char
ancho 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 a
y 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
Creo que esos serían campos de bits.
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.