2010-08-07 15 views
7

Ésta es la línea 519 de WinNT.h (Build Versión: 0091)¿Qué significa esta línea del preprocesador C/C++?

#define DECLARE_HANDLE(name) struct name##__{int unused;}; typedef struct name##__ *name 

¿Por qué necesitamos un puntero a una estructura con un solo miembro int con un nombre raro llamado unused?

¿Y alguna vez tendremos que usar una línea de código como esta?

HINSTANCE hInstance = new HINSTANCE__; 

En general declarar diferentes tipos de datos con las mismas estructuras, no tiene sentido para mí. ¿Cuál es la idea detrás de esto?

DECLARE_HANDLE(HRGN); 
DECLARE_HANDLE(HRSRC); 
DECLARE_HANDLE(HSPRITE); 
DECLARE_HANDLE(HLSURF); 
DECLARE_HANDLE(HSTR); 
DECLARE_HANDLE(HTASK); 
DECLARE_HANDLE(HWINSTA); 
DECLARE_HANDLE(HKL); 

Respuesta

1

Y alguna vez tenga que utilizar una línea de código como éste?
HINSTANCE hInstance = new HINSTANCE__;

Suele utilizar un valor HINSTANCE devuelto por una llamada al sistema de Windows; Nunca he visto código ejecutando una línea así.

10

El punto es que los diferentes identificadores tienen diferentes tipos para que, por ejemplo, un HINSTANCE no se pueda asignar a un HANDLE. Si todos fueron definidos como "void *", entonces hay clases de errores que el compilador no pudo detectar.

+0

Entonces, ¿la idea detrás de esto es tener tipos de datos enteros que no se utilizarán para fines distintos a los que fueron declarados? –

+0

Sí, eso proporciona seguridad de tipo para los tipos de asa, por lo que se obtiene un error cuando se intenta pasar un HINSTANCE a una función que requiere un MANGO aunque la estructura subyacente sea idéntica. (Esta respuesta iba a ser simplemente "sí", pero evidentemente no era lo suficientemente detallada. Se agregó una verbosidad adicional) – janm

+0

ahhh Veo por qué C no permite estructuras anónimas como parámetros para funciones ahora; si tratara las estructuras anónimas como iguales a cualquier estructura idéntica con la misma configuración, haría que C no cause errores para hacer que este truco funcione. Dicho esto, estoy bastante seguro de que permitirlo permitiría un código más flexible, pero al menos hay una razón. también parece indicar que existe una dependencia del código real de los punteros que son exactamente del tamaño de int, de lo contrario, el identificador se rompería y sería necesario volver a escribir mucho código. – Dmitry

0

En realidad, no apuntan a nada a la memoria; solo se usan para referirse a objetos (archivos, recursos, semáforos, ventanas) cuando se realizan llamadas a la API de Windows. Si bien no son más que solo índices en las tablas de objetos del núcleo, los desarrolladores decidieron que lo convierten en un puntero a una estructura no utilizada que los haría "opacos" y causaría menos confusión entre otros tipos. El DECLARE_HANDLE es una macro de función que hace precisamente eso: declarar tipos opacos para identificadores.