Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/react-native/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在C中使用函数指针时发出警告_C_Function Pointers_Compiler Warnings - Fatal编程技术网

在C中使用函数指针时发出警告

在C中使用函数指针时发出警告,c,function-pointers,compiler-warnings,C,Function Pointers,Compiler Warnings,这实际上是一个非关键性的问题,但我在使用函数指针的大多数情况下都会收到这个警告,但我自己仍然不知道为什么。考虑下面的原型: typedef void * Pointer; void tree_destroyLineage(Tree greatest_parent, void *dataDestructor(Pointer data)); 到目前为止,我可以编译我的千行代码,并得到零警告。所以我假设我写的声明是正确的。但我在代码中调用它,作为析构函数自由传递,因为树节点中存储的数据是简单的结构:

这实际上是一个非关键性的问题,但我在使用函数指针的大多数情况下都会收到这个警告,但我自己仍然不知道为什么。考虑下面的原型:

typedef void * Pointer;
void tree_destroyLineage(Tree greatest_parent, void *dataDestructor(Pointer data));
到目前为止,我可以编译我的千行代码,并得到零警告。所以我假设我写的声明是正确的。但我在代码中调用它,作为析构函数自由传递,因为树节点中存储的数据是简单的结构:

tree_destroyLineage(decision_tree, free);
这使我得到一个
“警告:从不兼容的指针类型传递'tree\u destroylegine'的参数2”
消息。我的第一个假设是编译器在编译时无法确定
指针
void*
是同一件事,因此我尝试用完全相同类型的函数指针创建另一个函数,以“重新传递”对
free()的调用
并将函数指针声明更改为接受
void*
而不是指针。两种方法在同一个地方都给了我同样的警告

我做错了什么?如何解决它?

试试这个:

void tree_destroyLineage(Tree greatest_parent, void (*dataDestructor)(void *data));
使用
typedef
作为空指针是非常愚蠢的


编辑:问题是,如果在
*dataDestructor
周围没有括号,编译器会认为函数返回
void*
,而不是
void
。括号告诉编译器函数返回的是
void
,但它是指向函数的指针。

我认为像free这样的函数的正确签名是:

void (*freefunc)(void*)
不是


我不确定你的库,但我的免费没有返回值(即,它是无效的)。它不会返回空指针

如果您希望第二个参数是指向返回void并将void指针作为参数的函数的指针,我相信您需要的是:

无效(*fn)(无效*)

而不是

void*fn(void*)

这就是你所拥有的

void tree_destroyLineage(Tree greatest_parent, 
                          void *dataDestructor(Pointer data));
应该是:

void tree_destroyLineage(Tree greatest_parent, 
                          void (*dataDestructor)(Pointer data));

使用typedef作为指针真是愚蠢。用void*。为什么这么刻薄?我不觉得这很愚蠢。。。你隐藏了指针被实现为
void*
,并将代码近似为自然语言的事实。这只是额外的键入,使代码变得混乱。任何C程序员都会理解void*,但他们必须查找指针才能理解它。它确实使代码更接近自然语言,但代码不应该被大声读出。我同意这是额外的输入,但因为人们对编码风格的偏好而称他们为傻瓜是没有意义的。很抱歉,如果我因为批评你而被认为过于苛刻,我可能选错了词。谢谢,即使我一直使用指针而不是“void*”,这也解决了这个问题。在JF的帖子之后,我意识到出了什么问题。谢谢,这让我看到了不同。我的析构函数被声明为void*而不是void,这导致了问题。谢谢你的帮助。正如我在我最初的帖子中的回复评论中所说的那样,我在构建自定义“通用”容器库时,从GLIB(GTK+“base”库)中获得了“typedeffing”void*的想法。所以,你可以责备他们,说他们愚蠢是的,我认为滑稽可笑的是:油嘴滑舌的整个想法是有缺陷的。他们基本上都是试图在C中写C++。当然,“更老的语言”在更古老的语言中的“模拟”功能是反逻辑的,所以我已经被告知了,但是GLIB的工作非常好。时间是一个严重的问题,当你必须只使用纯C语言,并且你要花时间实现上千种列表类型时,你应该真正关注你的混合贪婪bruteforce算法对它创建的所有树的作用。我认为一些GLib是愚蠢的(例如,gchar总是完全等同于char),但其他部分非常有用(如GHashTable)。
void tree_destroyLineage(Tree greatest_parent, 
                          void (*dataDestructor)(Pointer data));