开发者

Circular function pointer question in C

开发者 https://www.devze.com 2023-03-22 00:03 出处:网络
I am trying to figure out how to declare a function that returns a pointer to a function that returns a function. It\'s a circular pro开发者_如何学运维blem and I don\'t know if this can be done in c.

I am trying to figure out how to declare a function that returns a pointer to a function that returns a function. It's a circular pro开发者_如何学运维blem and I don't know if this can be done in c. This is an illustrative example of what I'm trying to do (it does not work):

typedef (*)(void) (*fp)(void);

fp funkA(void) {
    return funkB;
}

fp funkB(void) {
    return funkA;
}


To create completely circular types like this in C, you must use a struct (or union). In C99:

typedef struct fpc {
    struct fpc (*fp)(void);
} fpc;

fpc funkB(void);

fpc funkA(void) {
    return (fpc){ funkB };
}

fpc funkB(void) {
    return (fpc){ funkA };
}

In C89, you don't have compound literals, so you must do:

fpc funkA(void) {
    fpc rv = { funkB };
    return rv;
}

fpc funkB(void) {
    fpc rv = { funkA };
    return rv;    
}


Try this:

void (*(*f())())()

I always find cdecl worthy and useful for such tasks. Query for the above was

declare f as function returning pointer to function returning pointer to function returning void


What about this?

typedef void (*rfp)(void);
typedef rfp (*fp)(void);

This is not fully circular, but is very simple and could be ok for you.

A complete solution can be found on "Guru of the Week" with full explanation, and is this:

 struct FuncPtr_;
 typedef FuncPtr_ (*FuncPtr)();
 struct FuncPtr_
 {
     FuncPtr_( FuncPtr pp ) : p( pp ) { }
     operator FuncPtr() { return p; }
     FuncPtr p;
 };


 FuncPtr_ f() { return f; } // natural return syntax
 int main()
 {
    FuncPtr p = f();  // natural usage syntax
    p();
 }

Not so simple, but correct and portable...


I tried the following, which avoid indeed the circular problem, and so it is wrong in the context (and needs casting); though, if you don't need to be really circular nor strict, it works

#include <stdio.h>


typedef void *(*fp)(void);

fp funcB(void);

fp funcA(void)
{
  printf("funcA %p\n", funcB);
  return (fp)funcB;
}

fp funcB(void)
{
  printf("func B %p\n", funcA);
  return (fp)funcA;
}

int main()
{
  printf("%p %p\n", funcA, funcB);
  printf("%p %p\n", funcA(), funcB()); 
  return 0;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消