使用未知数量的参数通过引用调用函数
Calling functions by reference with unknown amount of parameters
为了仅通过名称调用函数,我想出了这段代码。这目前有效,但我不确定它是否是未定义的行为。任何人都可以对此有所了解,也许可以帮助我提出更好的解决方案。
#include <stdio.h>
typedef void (*FunctionCallback)();
void first(char *str);
void second(int , int);
FunctionCallback function[] = {&first, &second};
void first(char *str )
{
printf( "First: %s\n", str );
}
void second(int x, int y)
{
int answer;
answer = x +y;
printf("Second: %d\n", answer);
}
int main()
{
function[0]("Working");
function[1](6, 5);
return 0;
}
代码有效,但使用了在 C89 中标记为过时的旧式声明。用于调用函数的函数指针和被调用函数的类型必须兼容,并且传递的参数类型必须与定义的类型匹配。对于显示的代码,两者都是正确的。
请注意,此技术不适用于可变参数函数或参数不是 "self-promoting" 的函数,例如 short
或 float
类型的函数。
这应该没问题,如果你小心点。我认为 UB 可能仅在 first
的情况下,它期望 char*
,但已将 const char*
传递给它。也许在某些平台上,编译器将 const char*
的东西放在一些奇怪的地方,并且可写内存的地址不同。但那是异国情调的,假设的。
无论如何,要清楚,在 C:
typedef void (*FunctionCallback)();
是一种指向没有参数列表的函数的指针。所以它是兼容的,正如mafso所说。
typedef void (*FunctionCallback)(void);
表示指向需要零参数的函数的指针。这只会与其他采用零参数的函数兼容。 (注意它不同于 C++,其中 fun()
与 C 中的 fun(void)
相同)
编辑:
我要强调的是,每次仍然需要正确地论证。与此同时,编译器无法帮助你,所以,嗯,祝你好运。
我可以想象一个编译器,想要变得聪明,看到你永远不会存储任何 fun(const char*)
的地址,并使用它来优化你的代码,从而删除对 first
的调用.
为了仅通过名称调用函数,我想出了这段代码。这目前有效,但我不确定它是否是未定义的行为。任何人都可以对此有所了解,也许可以帮助我提出更好的解决方案。
#include <stdio.h>
typedef void (*FunctionCallback)();
void first(char *str);
void second(int , int);
FunctionCallback function[] = {&first, &second};
void first(char *str )
{
printf( "First: %s\n", str );
}
void second(int x, int y)
{
int answer;
answer = x +y;
printf("Second: %d\n", answer);
}
int main()
{
function[0]("Working");
function[1](6, 5);
return 0;
}
代码有效,但使用了在 C89 中标记为过时的旧式声明。用于调用函数的函数指针和被调用函数的类型必须兼容,并且传递的参数类型必须与定义的类型匹配。对于显示的代码,两者都是正确的。
请注意,此技术不适用于可变参数函数或参数不是 "self-promoting" 的函数,例如 short
或 float
类型的函数。
这应该没问题,如果你小心点。我认为 UB 可能仅在 first
的情况下,它期望 char*
,但已将 const char*
传递给它。也许在某些平台上,编译器将 const char*
的东西放在一些奇怪的地方,并且可写内存的地址不同。但那是异国情调的,假设的。
无论如何,要清楚,在 C:
typedef void (*FunctionCallback)();
是一种指向没有参数列表的函数的指针。所以它是兼容的,正如mafso所说。
typedef void (*FunctionCallback)(void);
表示指向需要零参数的函数的指针。这只会与其他采用零参数的函数兼容。 (注意它不同于 C++,其中 fun()
与 C 中的 fun(void)
相同)
编辑:
我要强调的是,每次仍然需要正确地论证。与此同时,编译器无法帮助你,所以,嗯,祝你好运。
我可以想象一个编译器,想要变得聪明,看到你永远不会存储任何 fun(const char*)
的地址,并使用它来优化你的代码,从而删除对 first
的调用.