que - estructuras en c++ pdf
¿Hay razones para evitar miembros de la estructura del campo de bits? (4)
Hace mucho tiempo que sabía que hay campos de bits en C y ocasionalmente los uso para definir estructuras densamente compactas:
typedef struct Message_s {
unsigned int flag : 1;
unsigned int channel : 4;
unsigned int signal : 11;
} Message;
Cuando leo el código fuente abierto, en cambio, a menudo encuentro máscaras de bits y operaciones de cambio de bit para almacenar y recuperar dicha información en campos de bits laminados a mano. Esto es tan común que no creo que los autores no conocieran la sintaxis del campo de bits, por lo que me pregunto si hay razones para rodar campos de bits a través de máscaras de bits y cambiar las operaciones en lugar de confiar en el compilador para generar código para obtener y configurar dichos campos de bits.
¿Hay razones para evitar bitfield-structs?
bitfield-structs vienen con algunas limitaciones:
- Los campos de bits dan como resultado un código no portátil. Además, la longitud del campo de bits tiene una gran dependencia del tamaño de la palabra.
- La lectura (usando
scanf()
) y el uso de punteros en los campos de bits no es posible debido a la falta de direccionabilidad. - Los campos de bits se utilizan para empaquetar más variables en un espacio de datos más pequeño, pero hacen que el compilador genere código adicional para manipular estas variables. Esto da como resultado un aumento tanto en el espacio como en la complejidad del tiempo.
- El operador
sizeof()
no puede aplicarse a los campos de bit, ya quesizeof()
produce el resultado en bytes y no en bits.
Entonces, si debes usarlos o no, depende. Lea más en ¿Por qué bit endianness es un problema en bitfields?
¿Por qué otros programadores usan manipulaciones de bits codificadas a mano en lugar de bitfields para empaquetar múltiples campos en una sola palabra?
Esta respuesta se basa en la opinión ya que la pregunta es bastante abierta:
Muchos programadores desconocen la disponibilidad de bitfields o no están seguros de su portabilidad y semántica precisa. Algunos incluso desconfían de la capacidad del compilador para producir el código correcto. Prefieren escribir código explícito que entiendan.
Como comentó Cornstalks, esta actitud está enraizada en la experiencia de la vida real, como se explica en este artículo .
- El diseño de la memoria real de Bitfield está definido por la implementación: si el diseño de la memoria debe seguir una especificación precisa, no se deben usar los campos de bits y pueden requerirse manipulaciones de bits codificadas a mano.
- La entrega de los valores firmados en los campos de bits con signos y firmados está definida por la implementación. Si los valores firmados se empaquetan en un rango de bits, puede ser más confiable codificar manualmente las funciones de acceso.
En muchos casos, es útil poder abordar grupos individuales de bits dentro de una palabra, o para operar una palabra como una unidad. El estándar actualmente no proporciona ninguna forma práctica y portátil para lograr tal funcionalidad. Si el código se escribe para usar bitfields y más tarde se vuelve necesario para acceder a múltiples grupos como una palabra, no habría una buena manera de acomodar eso sin volver a trabajar todo el código usando los campos de bit o deshabilitar optimizaciones de alias basadas en tipo, usando tipo de juego de palabras, y esperando que todo salga como se espera.
El uso de turnos y máscaras puede ser poco elegante, pero hasta que C proporcione un medio para tratar una secuencia de bits explícitamente designada dentro de un lvalor como otro lvalue, a menudo es la mejor manera de garantizar que el código se adaptará para satisfacer las necesidades.
No hay ninguna razón para eso. Bitfields son útiles y convenientes. Están en el uso común en los proyectos integrados. Algunas arquitecturas (como ARM) tienen incluso instrucciones especiales para manipular bitfields.
Simplemente compare el código (y escriba el resto de la función foo1) https://godbolt.org/g/72b3vY