使用重定义void指针指向匿名结构的指针?

ach*_*ora 17 c uefi

我正在使用与UEFI驱动程序相关的代码,我遇到了这个:

/* 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;
Run Code Online (Sandbox Code Playgroud)

完整的源代码在此路径 http://dox.ipxe.org/include_2ipxe_2efi_2efi_8h_source.html

这是我第一次遇到匿名结构,我无法弄清楚重新定义void *指向匿名结构的指针的逻辑."古怪的破坏尝试"暗示什么样的黑客攻击?

Who*_*aig 19

该库正在使用隐藏在EFI_HANDLE中保存的地址后面的内部数据对象上的信息.但是这样做,他们使代码容易受到意外错误的影响.

在C中,void*透明地转换为任何其他void*非非const数据指针类型而不发出警告(通过语言设计).

使用非void指针类型可确保EFI_HANDLE仅在EFI_HANDLE属于的位置使用.编译器的类型检查会在您将其传递到其他地方时将其传递到腹股沟中EFI_HANDLE,而不是指向其他内容的指针.

例如:因为void*,这将编译没有警告或错误

#include <string.h>

#define EFI_HANDLE void*

int main()
{
    EFI_HANDLE handle = NULL;

    strcpy(handle, "Something");
}
Run Code Online (Sandbox Code Playgroud)

将别名更改为:

typedef struct {} *EFI_HANDLE;
Run Code Online (Sandbox Code Playgroud)

将收获随后的"不兼容的指针类型"编译时错误.

最后,作为一个匿名结构,没有任何无意义的结构标记名称添加到您可以使用的已经污染的名称空间(意外或邪恶).


250*_*501 7

这不是一个匿名结构,而是一个没有标签的结构.

匿名结构只能作为另一个结构的成员存在,
并且它也必须没有标记1.

不允许定义不带任何成员的结构.您正在查看的代码是使用允许此操作的编译器扩展.

库正在执行此操作以隐藏用户的结构定义,同时保持类型安全.

然而,有一个更好的方法来做到这一点.如果你有一个隐藏的结构定义,你仍然可以定义一个指向它的不透明指针,它有一个类型,所以它是类型安全的:

struct hidden    //defined in a file and not exposed
{
    int a;
};
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

1(引用自:ISO/IEC 9899:201x 6.7.2.1结构和联合说明符13)
未命名的成员,其类型说明符是没有标记的结构说明符,称为匿名结构; 一个未命名的成员,其类型说明符是一个没有标记的联合说明符,称为匿名联合.匿名结构或联合的成员被视为包含结构或联合的成员.如果包含的结构或联合也是匿名的,则递归应用

  • 值得一提的是,在C标准的旧版本中,"匿名结构"并不作为单独的术语存在.对于那些版本,"匿名"只会被解释为普通英语单词,意思是"没有名字",对于结构类型来说,似乎完全公平地解释为"没有标签". (2认同)