功能回归

时间:2013-07-08 21:43:45

标签: c function

是否可以声明某些返回该类型的函数类型func_t func_t

换句话说,函数是否可以自行返回?

// func_t is declared as some sort of function pointer
func_t foo(void *arg)
{
  return &foo;
}

或者我是否必须使用void *和类型转换?

9 个答案:

答案 0 :(得分:15)

不,你不能在C中声明递归函数类型。除了在结构(或联合)中,不可能在C中声明递归类型。

现在对于void *解决方案,void *只能保证指向对象而不是指向函数的指针。能够转换函数指针和void *仅作为扩展名提供。

答案 1 :(得分:11)

结构的可能解决方案:

struct func_wrap
{
    struct func_wrap (*func)(void);
};

struct func_wrap func_test(void)
{
    struct func_wrap self;

    self.func = func_test;
    return self;
}

使用gcc -Wall进行编译没有发出任何警告,但我不确定这是否是100%可移植的。

答案 2 :(得分:3)

你不能将函数指针强制转换为void*(它们可以是不同的大小),但这不是问题,因为我们可以转换为另一个函数指针类型并将其强制转换为获取原始值。

typedef void (*fun2)();
typedef fun2 (*fun1)();

fun2 rec_fun()
{
    puts("Called a function");
    return (fun2)rec_fun;
}

// later in code...
fun1 fp = (fun1)((fun1)rec_fun())();
fp();

输出:

Called a function
Called a function
Called a function

答案 3 :(得分:2)

  

换句话说,函数是否可以自行返回?

这取决于你自己的意思;如果你的意思是指向自己的指针,那么答案是肯定的!虽然函数无法返回其类型,但函数可以返回指向自身的指针,然后可以在调用之前将此指针转换为适当的类型。

问题comp.lang.c faq: Function that can return a pointer to a function of the same type.

中解释了详细信息

查看我的answer了解详情。

答案 4 :(得分:0)

这样的事情:

typedef void* (*takesDoubleReturnsVoidPtr)(double);

void* functionB(double d)
{
    printf("here is a function %f",d);
    return NULL;
}

takesDoubleReturnsVoidPtr functionA()
{
    return functionB;
}

int main(int argc, const char * argv[])
{
    takesDoubleReturnsVoidPtr func = functionA();
    func(56.7);
    return 0;
}

答案 5 :(得分:0)

假设功能定义

T f(void)
{
  return &f;
}

f()返回类型T的值,但表达式&f的类型是“指向返回T的函数的指针”。 T是什么并不重要,表达式&f将始终是不同的,不兼容的类型T (*)(void)。即使T是指向函数的指针类型,例如Q (*)(void),表达式&f也将成为“指向函数的指针返回指针到函数”,或Q (*(*)(void))(void)

如果T是一个整数类型,其大小足以容纳函数指针值T (*)(void)转换为T并返回{{1} }在您的平台上有意义,您可能能够逃脱

之类的东西
T (*)(void)

但我至少可以想到几种根本不起作用的情况。老实说,与使用像查找表这样的东西相比,它的效用非常有限。

C只是设计用于处理与任何其他数据项一样的函数,而指向函数的指针不能与指向对象类型的指针互换。

答案 6 :(得分:0)

有一种方法,你试试这个:

typedef void *(*FuncPtr)();

void *f() { return f; }

int main() {
    FuncPtr f1 = f();
    FuncPtr f2 = f1();
    FuncPtr f3 = f2();
    return 0;
}

答案 7 :(得分:0)

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

typedef void *(*fptr)(int *);
void *start (int *);
void *stop (int *);
void *start (int *a) {
         printf("%s\n", __func__);
         return stop(a);
}
void *stop (int *a) {
         printf("%s\n", __func__);
         return start(a);
}
int main (void) {
         int a = 10;
         fptr f = start;
         f(&a);
         return 0;
}

答案 8 :(得分:-1)

如果您使用的是C ++,则可以创建State对象类型(假设状态机示例用法),其中您声明operator()通过引用返回State对象类型或指针。然后,您可以将每个状态定义为State的派生类,从operator()的实现中返回每个适当的其他派生类型。