可变参数函数到函数指针

用户10043112

有没有办法将可变参数函数转换为这样的函数指针,是否合法?我同时要求 C 和 C++,但由于这种结构存在于两种语言中,因此我将两个问题合二为一。

extern int test(int, ...);
auto testptr = (int(*)(int, int, long)) &test;

谢谢,杰克

灌木丛

在 C 中,这些类型兼容。

关于“兼容类型和复合类型”C 标准第 6.2.7 节对函数指针的兼容性做了以下说明:

3复合类型可以由两种兼容的类型构成;它是一种同时兼容这两种类型并满足以下条件的类型:

  • 如果两种类型都是数组类型,则应用以下规则:
    • 如果一种类型是已知常量大小的数组,则复合类型是该大小的数组。
    • 否则,如果一种类型是可变长度数组,其大小由未计算的表达式指定,则行为未定义。
    • 否则,如果一种类型是指定了大小的可变长度数组,则复合类型是该大小的可变长度数组。
    • 否则,如果一种类型是未指定大小的可变长度数组,则复合类型是未指定大小的可变长度数组。
    • 否则,两种类型都是大小未知的数组,复合类型是大小未知的数组。复合类型的元素类型是两种元素类型的复合类型。
  • 如果只有一种类型是带有参数类型列表的函数类型(函数原型),则复合类型是带有参数类型列表的函数原型。
  • 如果两种类型都是带参数类型列表的函数类型,则复合参数类型列表中每个参数的类型为对应参数的复合类型。

...

5示例 给定以下两个文件范围声明:

int f(int (*)(), double (*)[3]);
int f(int (*)(char *), double (*)[]);

该函数的结果复合类型为:

int f(int (*)(char *), double (*)[3]);

第 6.7.6.3p15 节指出:

对于要兼容的两个函数类型,都应指定兼容的返回类型。此外,参数类型列表(如果两者都存在)应在参数数量和省略号终止符的使用方面达成一致;相应的参数应具有兼容的类型。如果一种类型具有参数类型列表,而另一种类型由不属于函数定义的一部分且包含空标识符列表的函数声明符指定,则参数列表不应有省略号终止符,并且每个参数的类型应与应用默认参数提升所产生的类型兼容。如果一种类型具有参数类型列表,而另一种类型由包含(可能为空)标识符列表的函数定义指定,则两者应在参数数量上一致,并且每个原型参数的类型应与类型兼容这是由于将默认参数提升应用于相应标识符的类型而产生的。

在你的例子中:

int test(int, ...);

此功能与以下兼容:

int (*)();            // a function taking an unknown number of parameters and returns an int
int (*)(int, ...);    // a function taking an int and variable parameters after and returns an int

但不是:

int (*)(int, int, long);    // a function taking an int, an int, and a long, and returns an int

由于两种函数类型都指定了一个参数列表,而且由于参数的数量和省略号的使用不符,所以类型不兼容。根据第 6.3.2.3p8 节,尝试通过不兼容的指针调用函数会调用未定义的行为

指向一种类型函数的指针可以转换为指向另一种类型函数的指针,然后再返回;结果应与原始指针相等。如果使用转换后的指针调用类型与引用类型不兼容的函数,则行为未定义。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章