为什么需要指针转换中的(void *)?

时间:2017-03-27 07:40:31

标签: c pointers

在下面的代码中,为什么在指针转换过程中需要(VOID *)

一些上下文定义:

#define VOID      void
typedef unsigned char       UINT8;


ErrorDest = (EFI_ACPI_6_0_GENERIC_HARDWARE_ERROR_SOURCE_STRUCTURE *)
            (VOID *)
            ((UINT8 *)Hest + Hest->Header.Length);

2 个答案:

答案 0 :(得分:8)

我能看到的唯一原因是阻止编译器发出有关指针对齐的警告。

UINT8没有对齐要求。

struct可以根据其成员具有其他对齐要求。通常,结构的对齐要求与其成员的最大对齐要求相同。如果EFI_ACPI_6_0_GENERIC_HARDWARE_ERROR_SOURCE_STRUCTURE是一个opaque类型(即,它已声明,但其成员未知),或者如果它包含具有对齐要求的成员,则编译器可能会发出有关对齐的警告。

void*可能指向任何地址,但在将其转换为其他指针类型时会排除对齐警告,即使该类型可能具有对齐要求。

答案 1 :(得分:1)

正如另一个答案所指出的那样,原因可能是对齐。但它可能只是一个错误 - 试图躲避不兼容的指针类型错误。

在编写this_t* a = (that_t*)b;之类的代码时,您会收到有关不兼容类型的编译器错误。然后尝试通过编写

来修复此错误是一个常见的错误
this_t* a = (void*)(that_t*)b; // bad, dont do this

确实这会使编译器错误无效。而不是编译器错误,我们现在有一个运行时未定义的行为错误,因为严格的别名冲突。

如果EFI_ACPI_6_0_GENERIC_HARDWARE_ERROR_SOURCE_STRUCTURE不包含uint8_t []的成员,则问题中的代码会因严格的别名冲突而调用未定义的行为。