实际上,我不知道它的“可移植性”如何(在现有实现下,或者至少在您关心的实现子集下,它是否会按照您的预期运行)。
就C标准而言,它根本不可移植。您的程序具有未定义的行为,因为它通过类型 (int(*)(int, int)
与函数的实际类型不同(int(*)(int, int, int)
)。 (前者是用于define your add
功能;后者是表达式的类型fn
用作呼叫的前缀。)
这在C标准 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf,第 6.5.2.2 节第 9 段:
如果函数定义的类型与
表示(表达式的)表达式所指向的类型
称为函数,行为未定义。
(该链接指向 C11 标准 N1570 草案的 PDF。您会在该标准的其他版本中找到类似或可能相同的措辞。)
我的建议:不要这样做。
但请注意,多余的参数variadic函数(如printf()
声明为, ...
)被悄悄地忽略。例如,这是完全合法的:
printf("Ignore the arguments\n", 10, 20, 30);
如果您确实需要能够在不知道函数需要多少个参数的情况下调用该函数,那么这可能是一种可行的方法(尽管您将失去对与该函数匹配的任何参数的编译时类型检查), ...
).
对于非可变参数函数,您可以自由地将函数指针从一种类型转换为另一种类型,但每次调用时都必须转换回正确的类型。