【问题标题】:Can a pair of pointers to different functions taking different types of parameters be compatible?一对指向采用不同类型参数的不同函数的指针可以兼容吗?
【发布时间】:2015-07-24 11:41:34
【问题描述】:

我们可以将特定签名的函数地址放入定义为具有其他签名的函数指针中并无缝使用吗?

比如下面的代码

#include <stdio.h>

void print_n(int *pn) {
    printf("%d\n", *pn);
}

void print_n_wrapper(void *p) {
    print_n(p);
}

int main(void) {
    int n = 123;
    void (*f)(void *) = print_n_wrapper;
    f(&n);
    f = print_n;
    f(&n);
    return 0;
}

在我的机器上编译并运行良好。我是否以某种方式调用了未定义的行为?

【问题讨论】:

  • 是的,您正在调用 UB。这些指针类型不兼容。
  • 它可以找到,但编译器告诉你warning: assignment from incompatible pointer type

标签: c function-pointers language-lawyer undefined-behavior


【解决方案1】:

是的,是undefined behaviour

引用 C11,第 §6.3.2.3 章,指针,(强调我的

指向一种类型的函数的指针可以转换为指向另一种类型的函数的指针 键入并再次返回;结果应与原始指针比较。 如果转换 指针用于调用类型与引用类型不兼容的函数, 行为未定义。

关于“类型不兼容的函数”部分,兼容性的定义是这样的

对于要兼容的两种函数类型,两者都应指定兼容的返回类型。(146) 此外,参数类型列表,如果两者都存在,则应在数量上达成一致。 参数和省略号终止符的使用;相应的参数应有 兼容的类型。

这意味着,void *int * 应该是相同的类型,但它们不是。所以,函数也不是兼容类型。

【讨论】:

  • OP 询问他的两种不同的函数类型是否 兼容 ,所以你的答案应该是函数类型兼容意味着什么
【解决方案2】:

print_n_wrapper 中对print_n(p) 的调用定义的,因为您所做的只是将最初是int*void* 转换为int*

分配f = print_n;会给你带来麻烦。虽然赋值定义,但后续调用f(&amp;n)的行为未定义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-26
    • 2020-10-11
    • 1970-01-01
    • 2011-05-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多