转换函数指针

发布于 2024-12-19 07:02:17 字数 434 浏览 3 评论 0原文

如果我有一个声明为的原型:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

夏尔 2024-12-26 07:02:17

根据 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.

东京女 2024-12-26 07:02:17

在 GCC 中,此表达式:

bool_expr ? func1 : func2

给出此警告:

warning: pointer type mismatch in conditional expression

即使您没有打开特殊警告。

更重要的是,GCC 通过将两个表达式都转换为 void * 来解决这种指针类型不匹配的问题;那么,当您尝试将其强制转换回来时(无论是显式地使用 (int (*)(void*, void*)) ,还是隐式地通过将其传递给 foo),它会给出此警告:

warning: ISO C forbids conversion of object pointer to function pointer type

如果您启用迂腐。 做的原因是函数指针不必在内部实现为指向内存位置的指针,因此它可能不具有与常规“对象”指针相同的大小等。)

(ISO C 禁止这样 说,这:

foo((bool_expr ? (int (*)(void*, void*))func1 : (int (*)(void*, void*))func2));

应该是相对安全的,前提是 foo 将有效的 char 指针传递给 func1 或有效的 int指向func2的指针。

我猜想,在函数指针确实与 void * 不兼容的系统上,编译器不会解决不匹配的 bool_expr 问题? func1 : func2 支持 void * (尽管我还没有查阅这方面的规范)。

In GCC, this expression:

bool_expr ? func1 : func2

gives this warning:

warning: pointer type mismatch in conditional expression

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 to foo), it gives this warning:

warning: ISO C forbids conversion of object pointer to function pointer type

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:

foo((bool_expr ? (int (*)(void*, void*))func1 : (int (*)(void*, void*))func2));

should be relatively safe, provided that foo is passing valid char pointers to func1 or valid int pointers to func2.

And I would guess that, on a system where function pointers are truly incompatible with void *, a compiler wouldn't resolve the mismatch bool_expr ? func1 : func2 in favor of void * (though I haven't consulted the spec on this).

眼眸里的快感 2024-12-26 07:02:17

正如评论所发布的代码未编译。

FWIW,这将按照您对 VC2010 的预期进行编译和执行:

int func1(char *s1, char *s2) { printf("func1\n"); return 0; }
int func2(int *i1, int *i2)   { printf("func2\n"); return 0; }

void foo(int (*)(void *, void *));

int main(int argc, char** argv)
{
    foo(2 == argc ? (int(*)(void*,void*))func1 :
                    (int(*)(void*,void*))func2);

    return 0;
}

void foo(int (*a)(void *, void *))
{
    a((void*)0, (void*)0);
}

As commented the code as posted did not compile.

FWIW, this compiles and executes as you would expect with VC2010:

int func1(char *s1, char *s2) { printf("func1\n"); return 0; }
int func2(int *i1, int *i2)   { printf("func2\n"); return 0; }

void foo(int (*)(void *, void *));

int main(int argc, char** argv)
{
    foo(2 == argc ? (int(*)(void*,void*))func1 :
                    (int(*)(void*,void*))func2);

    return 0;
}

void foo(int (*a)(void *, void *))
{
    a((void*)0, (void*)0);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文