2008-11-05 12 views
30

Estoy leyendo El lenguaje de programación C++. En él, Stroustrup afirma que sizeof(char) == 1 y 1 <= sizeof(bool). Los detalles dependen de la implementación. ¿Por qué un valor tan simple como un booleano toma el mismo espacio que un char?¿Por qué un char y un bool tienen el mismo tamaño en C++?

+1

No son "del mismo tamaño". Como cualquier otro tipo, un 'bool' debe ser _al menos_ del mismo tamaño que un' char'. Pero es gratis para ser más grande. –

Respuesta

65

En arquitecturas informáticas modernas, un byte es la unidad de memoria direccionable más pequeña. Para empacar múltiples bits en un byte es necesario aplicar operaciones adicionales de cambio de bit. En el nivel del compilador, se trata de una compensación de la memoria frente a los requisitos de velocidad (y en el software de alto rendimiento, esas operaciones adicionales de cambio de bits pueden sumarse y ralentizar la aplicación innecesariamente).

11

Ocupa el mismo espacio, porque la menor cantidad de espacio que puede escribir en la memoria es de un solo byte. Ambos valores se almacenan en un byte. Aunque teóricamente solo necesitas 1 bit para indicar un valor booleano, igual tienes que tener un byte completo para almacenar el valor.

4

Teóricamente solo necesita un bit para bool, pero trabajar con menos de 1 byte de datos es complicado. Necesitas más instrucciones para lograr cualquier cosa y realmente no te beneficias.

Si desea empaquetar múltiples booleanos en un solo byte, puede usar un bit-field structure.

+0

Pero sería mejor que no lo hicieras. –

19

Porque en C++ puede tomar la dirección de un booleano y la mayoría de las máquinas no pueden direccionar bits individuales.

+0

cierto, pero puede falsificarlo sobrecargando el operador unario y devolviendo una clase de referencia de proxy :-P –

+4

El "puntero falso" resultante no sería representable como un char *, que el estándar de C++ requiere para que los punteros incorporen tipos (sin incluir puntero a función y puntero a miembro). Entonces, aunque es divertido para los tipos definidos por el usuario, el truco no puede ser utilizado por el compilador para bool. –

+0

Esta es la respuesta correcta. Una pregunta más interesante es por qué los autores del estándar no estaban dispuestos a reconocer la posibilidad de un tipo de "bit" independiente cuya dirección no se podía tomar, especialmente si reconoce el concepto de tales tipos dentro de las estructuras (usando bitfields), y dado que tales tipos se han usado durante mucho tiempo en el mundo C incrustado. No todos los enlazadores admitirían la granularidad más fina que un byte, pero un estándar podría permitir a los compiladores asignar variables de 'bit' por bit cuando sea conveniente sin requerir que lo hagan en cualquier circunstancia. – supercat

2

En realidad, en la mayoría de las implementaciones que conozco de sizeof (bool) == sizeof (int). "int" está destinado a ser el tamaño de datos que es más eficiente para que la CPU trabaje. Por lo tanto, las cosas que no tienen un tamaño específico (como "char") tienen el mismo tamaño que un int. Si tiene una gran cantidad de ellos por objeto, puede implementar un medio de empaquetarlos para su almacenamiento, pero durante el cálculo normal, debe dejarse en su tamaño original.

+0

si va a utilizar una matriz de booleanos, use std :: vector , tiene implementaciones especializadas para vectores de bits que solo usan un bit por elemento. –

+0

@mats: std :: bitset es menos loco. vector intenta y no puede ser un contenedor STL. También hay boost :: dynamic_bitset, que a diferencia de std :: bitset puede crecer. –

2

Hay algo en C++ llamado vector que intenta explotar el hecho de que teóricamente puedes almacenar 8 bools en un char, pero es ampliamente considerado como un error por el comité de estándares de C++. El libro "stl efectivo" en realidad dice "no lo use". Eso debería darte una idea de lo complicado que es.

Por cierto: Knuth tiene un book dedicado a las operaciones de bit a bit. Boost también tiene un library dedicado a manejar grandes cantidades de bits de una forma más eficiente en cuanto a la memoria.

+0

Te refieres a "vector llamado ** **". Cualquier otro tipo de 'vector' está perfectamente cuerdo. –

2

Un byte es la unidad de memoria direccionable más pequeña.

Considere el siguiente código:

bool b[9]; 
    bool *pb0 = &b[0]; 
    bool *pb1 = &b[1]; 

    for (int counter=0; counter<9; ++counter) 
    { 
     // some code here to fill b with values 
     b[counter] = true; 

    } 

Si bool se almacena en forma de 1 bit, entonces PB0 será igual PB1, porque ambos tienen la misma dirección. ¡Esto claramente no es deseable!

Además, la asignación en el bucle dará como resultado un código de ensamblaje no trivial. Implicará un cambio de bit diferente en cada iteración del ciclo. En el software de alto rendimiento, esas operaciones adicionales de cambio de bit pueden ralentizar la aplicación innecesariamente.

La biblioteca STL proporciona una solución alternativa en situaciones en las que el espacio sí importa. El uso de std :: vector < bool> almacenará bool como 1 bit.La paradoja del ejemplo anterior no se aplican porque

  • la sobrecarga del operador [] oculta los rigores de la operación de desplazamiento de bits
  • el uso de iteradores en lugar de punteros dan flexibilidad adicional para la implementación
Cuestiones relacionadas