In the following code, why need the (VOID *)
in the middle of pointer conversion?
Some Context definition:
#define VOID void
typedef unsigned char UINT8;
ErrorDest = (EFI_ACPI_6_0_GENERIC_HARDWARE_ERROR_SOURCE_STRUCTURE *)
(VOID *)
((UINT8 *)Hest + Hest->Header.Length);
The only reason I can see is to prevent the compiler from giving warnings about pointer alignment.
UINT8
has no alignment requirements.
A struct
can have other alignment requirements depending on its members. Ususally the alignment requirement of a struct is the same as the largest alignment requirement of its members. If EFI_ACPI_6_0_GENERIC_HARDWARE_ERROR_SOURCE_STRUCTURE
is an opaque type (that is, it is declared, but its members are unknown), or if it contains members with alignment requirements then the compiler may issue a warning about the alignment.
A void*
may point to any adress but is excempt from alignment warnings when it is cast to another pointer type, even if that type may have alignment requirements.
The reason might be alignment, as pointed out in another answer. But it might as well just be a bug - a failed attempt to dodge incompatible pointer type errors.
Upon writing code such as this_t* a = (that_t*)b;
you get a compiler error about incompatible types. It is then a somewhat common mistake to attempt to fix this error by writing
this_t* a = (void*)(that_t*)b; // bad, dont do this
Indeed this silences the compiler error. And instead of a compiler error, we now have a run-time undefined behavior bug, because of strict aliasing violation.
If EFI_ACPI_6_0_GENERIC_HARDWARE_ERROR_SOURCE_STRUCTURE
doesn't contain a member which is an uint8_t []
, then the code in the question invokes undefined behavior due to strict aliasing violation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With