[英]ISO C Void * and Function Pointers
在学习了一些教程并阅读有关函数指针的内容后,我了解到显然在ISO C中为函数指针指定了一个void指针是未定义的,有没有办法解决我在编译期间收到的警告(例如更好的编码方式)或我应该忽略它吗?
警告:
ISO C forbids assignment between function pointer and 'void *' [-pedantic]
示例代码:
void *(*funcPtr)();
funcPtr = GetPointer();
GetPointer是一个返回void指针EG的函数
void *GetPointer();
在tlpi-book中我发现这个技巧非常有趣:
#include <dlfcn.h>
int
main(int argc, char *argv[])
{
...
void (*funcp)(void); /* Pointer to function with no arguments */
...
*(void **) (&funcp) = dlsym(libHandle, argv[2]);
}
编号是正确的,您也是:在C89和C99中,您无法在数据指针( void *
is)和函数指针之间进行转换,因此解决警告的唯一方法是从函数返回一个函数指针。
(但是,请注意,实际上尽管有警告,这仍然有效,即使标准库中存在这种不一致 - dlsym()
函数用于获取函数指针,但它返回void *
- 所以基本上你可以忽略警告。它会起作用,虽然严格来说这里的行为是不明确的。)
我使用glib遇到了这个问题。 Glib数据结构(例如GSList)通常具有称为void * data的字段。 我想将函数存储在列表中并得到一堆类似于此的错误:
warning: ISO C forbids passing argument 2 of ‘g_slist_append’ between function pointer and ‘void *’ [-pedantic]
此示例使用gcc -Wall -ansi -pedantic生成一堆警告
typedef int (* func) (int);
int mult2(int x)
{
return x + x;
}
int main(int argc, char *argv[])
{
GSList *functions = NULL;
func f;
functions = g_slist_append(functions, mult2);
f = (func *) functions->data;
printf("%d\n", f(10));
return 0;
}
所以我将函数包装在一个结构中,并且所有警告都消失了:
struct funcstruct {
int (* func) (int);
};
int mult2(int x)
{
return x + x;
}
int main(int argc, char *argv[])
{
GSList *functions = NULL;
struct funcstruct p;
p.func = mult2;
functions = g_slist_append(functions, &p);
p = * (struct funcstruct *) functions->data;
printf("%d\n", p.func(10));
return 0;
}
有争议的是,这是一些额外的代码,使一些警告消失,但我不喜欢我的代码生成警告。 此外,以上是玩具示例。 在我正在编写的实际代码中,将结构中的函数列表包装起来非常有用。
我很想知道这是否有问题,或者是否有更好的方法。
基于@WeinanLi答案,但为了清晰起见使用辅助功能:
#include <dlfcn.h>
/* Pointer to function with no arguments */
typedef void (*functor_t)(void);
void load_symbol( functor_t* functor, void* dl_handle, const char* symbol_name ) {
*(void**)functor = dlsym( dl_handle, symbol_name );
}
int
main(int argc, char *argv[])
{
// [...]
functor_t funcp;
// [...]
load_symbol( &funcp, libHandle, argv[2]);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.