Search code examples
cuefi

Use of redefining void pointer to pointer to an anonymous structure?


I was working with UEFI driver-related code, and I came across this:

/* 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;

The full source code is in this path http://dox.ipxe.org/include_2ipxe_2efi_2efi_8h_source.html

This is my first encounter with anonymous structure, and I couldn't make out the logic of redefining a void * to a pointer to an anonymous structure. What kind of a hack the "bizzare sabotage attempt" hints at?


Solution

  • The library is using information hiding on the internal data object behind the address held in an EFI_HANDLE. But in doing so, they're making the code more susceptible to accidental bugs.

    In C, void* is transparently cast to any other non-void* non-const data pointer type without warning (it's by language design).

    Using a non-void pointer type ensures an EFI_HANDLE is only used where EFI_HANDLE belongs. The compiler's type-checking kicks you in the groin when you pass it somewhere else that isn't EFI_HANDLE , but rather a pointer to something else.

    Ex: As void*, this will compile without warning or error

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

    Changing the alias to:

    typedef struct {} *EFI_HANDLE;
    

    will reap the ensuing "incompatible pointer type" compile-time error.

    Finally, as an anonymous struct, there is no pointless structure tag name adding to the already-polluted name space that you can use (accidently or nefariously).