Namespaces
Variants

Bit-fields

From cppreference.net

Declara un miembro con ancho explícito, en bits. Los miembros de campo de bits adyacentes pueden empaquetarse para compartir y extenderse a través de los bytes individuales.

Una declaración de campo de bits es un struct o union miembro de declaración que utiliza el siguiente declarador :

identificador  (opcional) : ancho
identifier - un nombre para el campo de bits que se está declarando. El nombre es opcional: los campos de bits sin nombre introducen la cantidad especificada de bits de relleno
width - una expresión constante constant expression entera con un valor mayor o igual a cero y menor o igual al número de bits en el tipo subyacente. Cuando es mayor que cero, este es el número de bits que ocupará este campo de bits. El valor cero solo se permite para campos de bits sin nombre y tiene un significado especial: especifica que el siguiente campo de bits en la definición de la clase comenzará en el límite de una unidad de asignación.

Contenidos

Explicación

Los campos de bits solo pueden tener uno de los siguientes tipos (posiblemente const o volatile calificados):

  • unsigned int , para campos de bits sin signo (ej. unsigned int b : 3 ; tiene el rango [ 0 , 7 ] )
  • signed int , para campos de bits con signo ( signed int b : 3 ; tiene el rango [ - 4 , 3 ] )
  • int , para campos de bits con signo definido por la implementación (nótese que esto difiere del significado de la palabra clave int en cualquier otro lugar, donde significa "signed int"). Por ejemplo, int b : 3 ; puede tener el rango de valores [ 0 , 7 ] o [ - 4 , 3 ] .
  • _Bool , para campos de bits de un solo bit (por ejemplo, bool x : 1 ; ) tiene el rango [ 0 , 1 ] y las conversiones implícitas hacia y desde él siguen las reglas de conversión booleana.
(desde C99)
  • tipos enteros de precisión de bits (por ejemplo, _BitInt ( 5 ) : 4 ; tiene el rango [ - 8 , 7 ] y unsigned _BitInt ( 5 ) : 4 ; tiene el rango [ 0 , 15 ] ).
(desde C23)

Se pueden aceptar tipos adicionales definidos por la implementación. También está definido por la implementación si un campo de bits puede tener tipo atomic . (desde C11) El número de bits en un campo de bits ( width ) establece el límite del rango de valores que puede contener:

#include <stdio.h>
struct S
{
    // campo sin signo de tres bits,
    // los valores permitidos son 0...7
    unsigned int b : 3;
};
int main(void)
{
    struct S s = {7};
    ++s.b; // desbordamiento sin signo
    printf("%d\n", s.b); // salida: 0
}

Se permiten múltiples campos de bits adyacentes empaquetarse juntos (y usualmente se empaquetan):

#include <stdio.h>
struct S
{
    // normalmente ocupará 4 bytes:
    // 5 bits: valor de b1
    // 11 bits: sin usar
    // 6 bits: valor de b2
    // 2 bits: valor de b3
    // 8 bits: sin usar
    unsigned b1 : 5, : 11, b2 : 6, b3 : 2;
};
int main(void)
{
    printf("%zu\n", sizeof(struct S)); // normalmente imprime 4
}

El campo de bits sin nombre especial de width cero rompe el relleno: especifica que el siguiente campo de bits comienza al principio de la siguiente unidad de asignación:

#include <stdio.h>
struct S
{
    // normalmente ocupará 8 bytes:
    // 5 bits: valor de b1
    // 27 bits: sin usar
    // 6 bits: valor de b2
    // 15 bits: valor de b3
    // 11 bits: sin usar
    unsigned b1 : 5;
    unsigned    : 0; // inicia un nuevo unsigned int
    unsigned b2 : 6;
    unsigned b3 : 15;
};
int main(void)
{
    printf("%zu\n", sizeof(struct S)); // normalmente imprime 8
}

Debido a que los campos de bits no necesariamente comienzan al inicio de un byte, no se puede tomar la dirección de un campo de bits. No es posible tener punteros a campos de bits. Los campos de bits no pueden utilizarse con sizeof y _Alignas (desde C11) (hasta C23) alignas (desde C23) (desde C11) .

Notas

Los siguientes usos de campos de bits causan comportamiento indefinido :

Las siguientes propiedades de los campos de bits son no especificadas :

  • Alineación de la unidad de asignación que contiene un campo de bits.

Las siguientes propiedades de los campos de bits son definidas por la implementación :

  • Si los campos de bits de tipo int se tratan como con signo o sin signo.
  • Si se permiten tipos distintos de int , signed int , unsigned int , _Bool (desde C99) , y (posiblemente unsigned ) _BitInt ( N ) (desde C23) .
  • Si los tipos atómicos están permitidos.
(desde C11)
  • Si un campo de bits puede extenderse más allá del límite de una unidad de asignación.
  • El orden de los campos de bits dentro de una unidad de asignación (en algunas plataformas, los campos de bits se empaquetan de izquierda a derecha, en otras de derecha a izquierda).

Aunque el número de bits en la representación del objeto de _Bool es al menos CHAR_BIT , el ancho del campo de bits de tipo _Bool no puede ser mayor que 1 .

(desde C99)

En el lenguaje de programación C++, el ancho de un campo de bits puede exceder el ancho del tipo subyacente (pero los bits adicionales son bits de relleno), y los campos de bits de tipo int siempre son con signo.

Referencias

  • Estándar C23 (ISO/IEC 9899:2024):
  • 6.7.2.1 Especificadores de estructura y unión
  • Estándar C17 (ISO/IEC 9899:2018):
  • 6.7.2.1 Especificadores de estructura y unión
  • Estándar C11 (ISO/IEC 9899:2011):
  • 6.7.2.1 Especificadores de estructura y unión
  • Estándar C99 (ISO/IEC 9899:1999):
  • 6.7.2.1 Especificadores de estructura y unión
  • Estándar C89/C90 (ISO/IEC 9899:1990):
  • 3.5.2.1 Especificadores de estructura y unión

Véase también