punteros puntero lenguaje ejemplos arreglos apuntadores c uefi

ejemplos - punteros void lenguaje c



¿Uso de la redefinición del puntero de vacío para apuntar a una estructura anónima? (2)

Estaba trabajando con el código relacionado con el controlador UEFI , y encontré esto:

/* EFI headers define EFI_HANDLE as a void pointer, which renders type * checking somewhat useless. Work around this bizarre sabotage * attempt by redefining EFI_HANDLE as a pointer to an anonymous * structure. */ #define EFI_HANDLE STUPID_EFI_HANDLE #include <ipxe/efi/Uefi/UefiBaseType.h> #undef EFI_HANDLE typedef struct {} *EFI_HANDLE;

El código fuente completo se encuentra en esta ruta http://dox.ipxe.org/include_2ipxe_2efi_2efi_8h_source.html

Este es mi primer encuentro con una estructura anónima, y ​​no pude entender la lógica de redefinir un void * a un puntero a una estructura anónima. ¿Qué tipo de piratería sugiere el "intento de sabotaje de bizzare"?


Eso no es una estructura anónima, sino una estructura sin etiqueta.

Una estructura anónima solo puede existir como miembro de otra estructura,
y tampoco debe tener una etiqueta 1 .

No se permite definir una estructura sin miembros. El código que estás viendo está usando una extensión de compilador que lo permite.

La biblioteca está haciendo esto para ocultar la definición de la estructura del usuario, mientras mantiene la seguridad de tipos.

Sin embargo, hay una manera mucho mejor de hacer esto. Si tiene una definición de estructura oculta, todavía puede definirle un puntero opaco, que tiene un tipo, por lo que es seguro:

struct hidden //defined in a file and not exposed { int a; };

void Hidden( struct hidden* ); void Other( struct other* ); struct hidden* a = NULL; //doesn''t see the definition of struct hidden Hidden( a ); //it may be used Other( a ); //compiler error

1 (Citado de: ISO / IEC 9899: 201x 6.7.2.1 Especificadores de estructura y unión 13)
Un miembro sin nombre cuyo especificador de tipo es un especificador de estructura sin etiqueta se denomina estructura anónima; un miembro sin nombre cuyo especificador de tipo es un especificador de unión sin etiqueta se denomina unión anónima. Los miembros de una estructura o unión anónima se consideran miembros de la estructura o unión que los contiene. Esto se aplica recursivamente si la estructura que contiene o la unión es también anónima


La biblioteca está utilizando información que se oculta en el objeto de datos interno detrás de la dirección contenida en un EFI_HANDLE. Pero al hacerlo, hacen que el código sea más susceptible a errores accidentales.

En C, void* se convierte de forma transparente a cualquier otro tipo de puntero de datos no- void* non-const sin aviso (es por diseño de idioma).

El uso de un tipo de puntero no vacío anula que un EFI_HANDLE solo se use donde pertenece EFI_HANDLE . La comprobación de tipos del compilador le da una patada en la ingle cuando la pasa a otro lugar que no es EFI_HANDLE , sino más bien un puntero a otra cosa.

Ej: Como void* , esto se compilará sin advertencia o error

#include <string.h> #define EFI_HANDLE void* int main() { EFI_HANDLE handle = NULL; strcpy(handle, "Something"); }

Cambiando el alias a:

typedef struct {} *EFI_HANDLE;

cosechará el error de tiempo de compilación "tipo de puntero incompatible" resultante.

Finalmente, como una estructura anónima, no hay un nombre de etiqueta de estructura sin sentido que se agregue al espacio de nombres ya contaminado que puede usar (de forma accidental o inútil).