31

Is it possible to declare some function type func_t which returns that type, func_t?

In other words, is it possible for a function to return itself?

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

Or would I have to use void * and typecasting?

4

10 回答 10

18

结构的可能解决方案:

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% 可移植的。

于 2013-07-28T04:59:31.830 回答
18

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

现在对于void *解决方案,void *只保证保存指向对象的指针而不是指向函数的指针。能够转换函数指针并且void *只能作为扩展使用。

于 2013-07-08T21:45:25.063 回答
4

您不能将函数指针转换为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
于 2013-07-08T22:40:35.700 回答
3

换句话说,函数是否有可能返回自身?

这取决于您所说的“本身”是什么意思;如果您的意思是指向自身的指针,那么答案是肯定的!虽然函数不可能返回其类型,但函数可以返回指向自身的指针,然后可以在调用之前将此指针转换为适当的类型。

问题comp.lang.c faq中解释了详细信息:可以返回指向相同类型函数的指针的函数。

查看我的答案以获取详细信息。

于 2016-09-14T11:18:50.960 回答
1

假设函数定义

T f(void)
{
  return &f;
}

f()返回一个 type 的值T,但表达式的类型&f是“指向函数返回的指针T”。不管是什么T,表达式&f总是属于不同的、不兼容的类型T (*)(void)。即使T是指向函数的类型,例如Q (*)(void),表达式&f最终也会变成“指向函数的指针返回函数指针”,或者Q (*(*)(void))(void)

如果T是一个足够大的整数类型来保存函数指针值,并且T (*)(void)在您的平台上T来回转换是T (*)(void)有意义的,那么您可能能够摆脱类似的事情

T f(void)
{ 
  return (T) &f;
}

但我至少可以想到几种根本行不通的情况。老实说,与使用查找表之类的东西相比,它的实用性非常有限。

C 的设计初衷并不是像对待任何其他数据项一样处理函数,而且指向函数的指针不能与指向对象类型的指针互换。

于 2013-07-09T05:41:43.223 回答
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;
}
于 2013-07-08T21:57:27.807 回答
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;
}
于 2019-06-08T22:31:03.127 回答
0

函数不可能按值返回自身。但是,它本身可以通过指针返回。

C 允许定义采用未定义数量参数的函数类型,并且这些类型与采用已定义参数的函数类型兼容。

例如:

typedef void fun_t();

void foo(int);
fun_t *fun = foo; // types are fine

因此,以下功能将起作用。

void fun(void (**ptr)()) {
    *ptr = &fun;
}

您可以在下面找到示例用法:

#include <stdio.h>

void fun(void (**ptr)()) {
    puts("fun() called");
    *ptr = &fun;
}

int main() {
    void (*fp)();
    fun(&fp); /* call fun directly */
    fp(&fp);  /* call fun indirectly */
    return 0;
}

该代码以迂腐模式编译,没有 C89 标准的警告。它产生预期的输出:

fun() called
fun() called
于 2022-01-23T11:41:30.173 回答
-1

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

typedef void *(*FuncPtr)();

void *f() { return f; }

int main() {
    FuncPtr f1 = f();
    FuncPtr f2 = f1();
    FuncPtr f3 = f2();
    return 0;
}
于 2016-12-09T17:56:18.527 回答
-2

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

于 2013-07-08T23:32:42.917 回答