[英]Is There C Syntax For Function Pointer From Function Declaration
而不是为函数声明函数指针typedef,是否可以从函数声明中获取它?
通常情况下,
int foo(int x);
typedef int (*fooFunc)(int);
fooFunc aFunc;
我想要的是:
int foo(int x);
foo* aFunc;
我想将它用于dlsym:
foo* aFunc;
aFunc = dlsym(lib, "foo");
aFunc(x);
如果我更新foo并忘记更新fooFunc,反之亦然,那将是不好的。 此外,我可能有许多函数,维护函数声明和与这些函数关联的函数指针typedef会更加有效。
结论:AndreyT的答案是最便携的,但如果您编写gcc代码,那么typeof是一个很好的解决方案。
如果你正在谈论一个特定的声明 ,即一个函数的非定义声明,你可以通过为函数类型定义一个typedef-name并在两种情况下使用它来删除冗余 - 声明函数本身并声明一个指针对它,像这样
typedef int FuncType(int); /* <- function type */
FuncType foo; /* <- declaration of `int foo(int)` */
FuncType *aFunc; /* <- definition of `int (*aFunc)(int)` */
即typedef-names可用于非定义函数声明。 但是,您不能在函数定义中使用typedef名称,这意味着以后您仍然需要这样做
int foo(int x) /* <- no way to use the above `FuncType` here */
{
/* whatever */
}
这基本上使上述技巧几乎无用。
当然,如果这是您的情况,这不会帮助您从现有的不可修改的函数声明生成指针。
如果你有gcc, typeof工作。
更新
$ cat fxf.c
#include <stdio.h>
int main(int argc, char **argv) {
typedef __typeof__ (main) function_of_same_type_as_main_t;
function_of_same_type_as_main_t *f;
printf("main() called.\n");
f = main;
if (argc) f(0, NULL);
return 0;
}
$ /usr/bin/gcc -std=c89 -pedantic -Wall -Wextra -o fxf fxf.c fxf.c:3: warning: unused parameter ‘argv’
$ ./fxf main() called. main() called.
答案简单:不,那不行。 foo
是一个具有原型( int (int)
)的特定函数。 以你的方式使用foo
有点像使用int
来声明另一个int
:
4 x; // expect this to be the same as int x
也就是说,可能有编译器扩展可以使其工作。 我知道即将推出的C ++标准将允许使用decltype
关键字。 使用它,以下可能会工作(未经测试,因为我没有支持编译器方便):
int foo(int x);
decltype(&foo) aFunc = dlsym(lib, "foo");
这不可能。 但是,您可以编写一些会生成警告的代码,以便捕获类型不匹配。 以下代码从不兼容的指针类型警告生成分配。
#include <stdio.h>
int foo(int, int);
typedef int(*fooFunc)(int);
fooFunc myfunc;
int foo(int x, int y)
{
return 2*x + y;
}
int main(int argc, char **argv)
{
myfunc = foo;
printf("myfunc : 0x%x\n", (unsigned int)myfunc);
return 0;
}
当然,这意味着您必须在foo函数可见的情况下编写此测试代码,因此这仍然需要为每种函数类型添加更多代码。 这里的解决方案可能是一个代码生成器,它会生成一个包含函数及其相关typedef的正确头文件
不完全相同,但您可以键入def函数并将其用于原型和指针。
typedef int fooFunc(int);
fooFunc foo;
fooFunc *aFunc;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.