通过评论我的回答启发这里。
此步骤顺序在C标准(C11)中合法吗?
void*
void*
或等效地作为代码:
void foo(void) { ... }
void bar(void) { ... }
typedef void (*voidfunc)(void);
voidfunc array[] = {foo, bar}; // Step 1
void *ptr1 = array; // Step 2
void *ptr2 = (char*)ptr1 + sizeof(voidfunc); // Step 3
voidfunc bar_ptr = *(voidfunc*)ptr2; // Step 4
我认为这将被允许,因为实际的函数指针只能通过正确键入的指针来访问。但是安德鲁·亨利(Andrew Henle)指出,标准6.3.2.3:指针似乎并未涵盖这一点。
是的,代码很好。这里有各种陷阱和转换规则:
void*
是指向对象类型的指针的通用指针类型。指向对象类型的任何指针都可以void*
隐式地转换为from / from 。(C17 6.3.2.3§1)。void*
,反之亦然。(C17 6.3.2.3§1)void(*)(void)
通用函数指针类型之类的东西。只要您不通过错误的函数指针类型调用函数,就可以了。(C17 6.3.2.3§8)函数指针指向函数,但它们本身就是对象,就像任何指针一样。因此,您可以使用avoid*
指向函数指针的地址。
因此,使用avoid*
指向函数指针就可以了。但是不能用它直接指向一个函数。如果void *ptr1 = array;
数组衰减为指向第一个元素的指针,则a void (**)(void)
(相当于voidfunc*
您的示例)。您可以使用指向此类指向函数指针的指针void*
。
此外,关于指针算法:
void*
。(C17 6.3.2.2)这种算术运算是应避免的常见非标准扩展。而是使用指向字符类型的指针。因此,(char*)ptr1 + sizeof(voidfunc);
也可以。然后,您从转换void*
为voidfunc*
,voidfunc
这是数组中存储的原始函数指针类型。
如注释中所述,可以通过typedef
对函数类型使用a来显着提高此代码的可读性:
typedef void (voidfunc)(void);
voidfunc* array[] = {&foo, &bar}; // Step 1
void* ptr1 = array; // Step 2
void* ptr2 = (char*)ptr1 + sizeof(voidfunc*); // Step 3
voidfunc* bar_ptr = *(voidfunc**)ptr2; // Step 4
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句