2012-06-20 16 views
6
// <windef.h> 

typedef int     BOOL; 

¿No es esto una pérdida de memoria ya que un int es de 32 bits?¿Por qué WinAPI usa un int (32 bits) para el tipo BOOL?

Sólo en caso de que estaba mal, he intentado el envío de una normal de bool* a una función que requiere BOOL* y no funcionó hasta que use el int typedef.

+5

érase una vez, 'bool' no era del tipo C. Ver http://stackoverflow.com/questions/1608318/is-bool-a-native-c-type – dyp

+1

oman Soy tan tonto, soy real dum real – y2k

+0

. Sabía que PERO bool se había agregado a C, entonces, ¿qué es el HOLDUP? AQUÍ – y2k

Respuesta

17

Vaya, reduzca la velocidad un poco allí. En primer lugar, estoy bastante seguro de que los programadores han estado utilizando 4-byte int s para variables booleanas desde el comienzo de la programación en x86. (No solía haber un tipo de datos bool). Y me atrevería a adivinar que este mismo typedef está en Windows 3.1 <Windows.h>.

En segundo lugar, debe comprender un poco más sobre la arquitectura. Usted tiene una máquina de 32 bits, lo que significa que todos los registros de la CPU son de 4 bytes o 32 bits de ancho. Por lo tanto, para la mayoría de los accesos a memoria, es más eficiente para almacenar y acceder a los valores de 4 bytes que para un valor de 1 byte.

Si tiene cuatro variables booleanas de 1 byte empaquetadas en un fragmento de 4 bytes de memoria, tres de ellas no están alineadas DWORD (4 bytes). Esto significa que la CPU/controlador de memoria realmente tiene que hacer más trabajar para obtener el valor.

Y antes de ir a romper en MS para hacer ese typedef "derrochador". Considere esto: Bajo el capó, la mayoría de los compiladores (probabily) todavía implementan el tipo de datos bool como un byte int por las mismas razones que acabo de mencionar. Pruébelo en gcc, y eche un vistazo al archivo del mapa. Apuesto a que estoy en lo cierto.

+1

Esto, los problemas de alineación con 1 byte son horrendos con un registro de tamaño estándar. – TheZ

+3

En x86, sin embargo, es tan fácil obtener 1 byte como lo es 4. Los problemas de alineación entran en juego cuando tiene valores de múltiples bytes. La mayor ineficiencia es que estás leyendo 4 bytes cuando 1 lo hará ... pero de cualquier manera toma la misma cantidad de tiempo. – cHao

+2

El argumento histórico es válido, el resto no. GCC produce un bool de 1 byte. Cargar/almacenar 1 byte es definitivamente diferente a nivel de chip y tiene diferentes implicaciones para el almacenamiento en caché, la alineación y la concurrencia que la carga de 4 bytes. –

2

El procesador tiene 32 bits y tiene un indicador especial cuando opera en un entero cero, por lo que las pruebas de valores booleanos de 32 bits son muy, muy, muy rápidas.

La prueba de un valor booleano de 1 bit o de un byte va a ser mucho más lento.

Si le preocupa el espacio de memoria, entonces puede que le preocupen las variables bool de 4 bytes.

La mayoría de los programadores, sin embargo, están más preocupados por el rendimiento, y por lo tanto el valor predeterminado es usar el bool más rápido de 32 bits.

Es posible que pueda obtener su compilador para optimizar el uso de la memoria si esto le molesta.

+1

@cHao sí, pero tienes que trabajar más para obtener ese byte de la memoria. Necesita tirar al menos 32 bits y enmascararlo. –

+2

Además, la mayoría de las CPU x86 actualmente son de 32 bits. - tienen buses de datos de 64 bits (Intel lo ha hecho desde P6, creo ... tal vez incluso el Pentium original), por lo que el enmascaramiento y/o el cambio todavía * necesitarían hacer. – cHao

13

En primer lugar, el tipo utilizado en la API del sistema tiene que ser lo más independiente posible del idioma, ya que esa API será utilizada por una multitud de lenguajes de programación. Por esta razón, cualquier tipo "conceptual" que podría no existir en algunos idiomas o implementarse de manera diferente en otros idiomas está fuera de toda duda. Por ejemplo, bool encaja en esa categoría. Además de eso, en una API de sistema es una muy buena idea mantener el número de tipos de interfaz al mínimo. Todo lo que se pueda representar por int debe estar representado por int.

En segundo lugar, su afirmación de que esto es "un desperdicio de memoria" no tiene sentido en absoluto. Para convertirse en "un desperdicio de memoria", uno tendría que crear un tipo de datos agregado que involucre un número extremadamente grande de elementos BOOL. La API de Windows no utiliza tales tipos de datos. Si construiste un tipo de datos tan derrochador en tu programa, en realidad es tu culpa. Mientras tanto, la API de Windows no te obliga de ninguna manera a almacenar tus valores booleanos en el tipo BOOL. Puede usar bytes e incluso bits para ese fin.En otras palabras, BOOL es un tipo de interfaz puramente . Objeto del tipo BOOL normalmente no ocupa ninguna memoria a largo plazo en absoluto, si lo está utilizando correctamente.

+3

@DyP: No realmente. AFAIK hay idiomas existentes que no admiten tipos de 1 byte simplemente porque no tienen ninguna razón para hacerlo. – AnT

+2

@AndreyT Solo piense en todos los tipos de datos que BF no admite ... –

+0

Todavía me gusta la forma en que usted explicó esto. Estamos lidiando con ** API **, no con una estructura de datos. –

2

Históricamente BOOL se usó como anything-not-0 = TRUE tipo. Por ejemplo, un procedimiento de diálogo devolvió un BOOL, que podría llevar mucha información. La firma abajo es de Microsoft's own documentation:

BOOL CALLBACK DlgProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) 

El resultado de la firma y la función combinó varios problemas, por lo que es in the modern API lugar

INT_PTR CALLBACK DialogProc(
    _In_ HWND hwndDlg, 
    _In_ UINT uMsg, 
    _In_ WPARAM wParam, 
    _In_ LPARAM lParam 
); 

Esta declaración de última moda tiene que seguir siendo compatible con el antiguo. Lo que significa que INT_PTR y BOOL tienen que ser del mismo tamaño. Lo que significa que en la programación de 32 bits, BOOL es de 32 bits.

En general, desde BOOL puede ser cualquier valor, no solo 0 y 1, es una idea muy poco buena para comparar un BOOL a TRUE. Y a pesar de que funciona para compararlo contra FALSE, generalmente también es una mala práctica porque puede dar a la gente la impresión de que comparar con TRUE sería correcto. Además, porque es bastante innecesario.

Por cierto, hay más tipos booleanos en el API de Windows, en particular VARIANT_BOOL que es de 16 bits y donde lógico TRUE se representa como todo 1 la bitpattern, es decir -1 como un valor firmado y hellip;

Esa es una razón adicional por la que no es una buena idea comparar directamente con FALSE lógico o VERDADERO.

Cuestiones relacionadas