转换函数指针

时间:2011-11-30 23:18:38

标签: c casting function-pointers

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

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 *))

3 个答案:

答案 0 :(得分:2)

根据C规范,转换函数指针导致未指定的行为,但许多编译器(例如gcc)执行您期望它们执行的操作,因为函数指针只是内存中的地址。为了安全起见,我将重新声明func1和func2以获取void *,然后根据需要将这些指针强制转换为char *和int *。

答案 1 :(得分:1)

评论时发布的代码没有编译。

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);
}

答案 2 :(得分:1)

在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禁止这一点的原因是函数指针不必在内部实现为指向内存位置的指针,因此它可能不具有与常规“对象”指针相同的大小和其他内容。)< / p>

那说,这个:

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

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

我猜想,在函数指针真正与void *不兼容的系统上,编译器无法解决错误bool_expr ? func1 : func2而转而支持void *(尽管我没有没有参考这个规范。

相关问题