转换函数指针
如果我有一个声明为的原型:
void foo(int (*fi)(void *, void *))
我用这样的方式调用该函数:
foo(int (*)(void*, void*)(bool_expr ? func1 : func2));
其中 func1 和 func2 定义如下:
int func1(char *s1, char *s2);
int func2(int *i1, int *i2);
函数调用是否将函数之一 (func1 ^ func2) 转换为所需函数的类型通过 foo?我还可以让 foo 的原型看起来像:
void foo(int (*)(void *, void *))
If I have a prototype that is declared as:
void foo(int (*fi)(void *, void *))
And I call the function with something like this:
foo(int (*)(void*, void*)(bool_expr ? func1 : func2));
Where func1 and func2 are defined as follows:
int func1(char *s1, char *s2);
int func2(int *i1, int *i2);
Is the function call casting one of the functions (func1 ^ func2) to the type of the function required by foo? Could I also make the prototype for foo look like:
void foo(int (*)(void *, void *))
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
根据 C 规范,转换函数指针会导致未指定的行为,但许多编译器(例如 gcc)会执行您期望它们执行的操作,因为函数指针只是内存中的一个地址。为了安全起见,我将重新声明 func1 和 func2 以采用 void*,然后根据需要将这些指针强制转换为 char* 和 int*。
According to C specification, casting function pointers results in unspecified behavior, but many compilers (e.g. gcc) do what you expect them to do, because function pointer is just an address in memory. Just to be safe, I would re-declare func1 and func2 to take void*, and then cast these pointers to char* and int* as required.
在 GCC 中,此表达式:
给出此警告:
即使您没有打开特殊警告。
更重要的是,GCC 通过将两个表达式都转换为
void *
来解决这种指针类型不匹配的问题;那么,当您尝试将其强制转换回来时(无论是显式地使用(int (*)(void*, void*))
,还是隐式地通过将其传递给foo
),它会给出此警告:如果您启用迂腐。 做的原因是函数指针不必在内部实现为指向内存位置的指针,因此它可能不具有与常规“对象”指针相同的大小等。)
(ISO C 禁止这样 说,这:
应该是相对安全的,前提是
foo
将有效的char
指针传递给func1
或有效的int
指向func2
的指针。我猜想,在函数指针确实与 void * 不兼容的系统上,编译器不会解决不匹配的 bool_expr 问题? func1 : func2 支持
void *
(尽管我还没有查阅这方面的规范)。In GCC, this expression:
gives this warning:
even if you don't turn on special warnings.
What's more, GCC resolves this pointer-type mismatch by casting both expressions to
void *
; so then, when you try to cast it back (either explicitly, with(int (*)(void*, void*))
, or implicitly, by passing it tofoo
), it gives this warning:if you enable pedantry. (The reason that ISO C forbids this is that a function pointer does not have to be implemented, internally, as a pointer to a memory location, so it may not have the same size and whatnot as a regular "object" pointer.)
That said, this:
should be relatively safe, provided that
foo
is passing validchar
pointers tofunc1
or validint
pointers tofunc2
.And I would guess that, on a system where function pointers are truly incompatible with
void *
, a compiler wouldn't resolve the mismatchbool_expr ? func1 : func2
in favor ofvoid *
(though I haven't consulted the spec on this).正如评论所发布的代码未编译。
FWIW,这将按照您对 VC2010 的预期进行编译和执行:
As commented the code as posted did not compile.
FWIW, this compiles and executes as you would expect with VC2010: