Вопрос указателя круговой функции в C - PullRequest
7 голосов
/ 22 июля 2011

Я пытаюсь выяснить, как объявить функцию, которая возвращает указатель на функцию, которая возвращает функцию. Это круговая проблема, и я не знаю, можно ли это сделать в c. Это наглядный пример того, что я пытаюсь сделать (это не работает):

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

fp funkA(void) {
    return funkB;
}

fp funkB(void) {
    return funkA;
}

Ответы [ 4 ]

6 голосов
/ 22 июля 2011

Чтобы создать полностью круглые типы, подобные этому, в C, вы должны использовать struct (или union).В C99:

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

fpc funkB(void);

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

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

В C89 у вас нет составных литералов, поэтому вы должны сделать:

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

fpc funkB(void) {
    fpc rv = { funkA };
    return rv;    
}
4 голосов
/ 22 июля 2011

Попробуйте это:

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

Я всегда нахожу cdecl достойным и полезным для таких задач. Запрос на выше был

declare f as function returning pointer to function returning pointer to function returning void
1 голос
/ 22 июля 2011

Как насчет этого?

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

Это не полностью круглая, но очень простая и может быть хорошо для вас.

Полное решение можно найти на "Гуру недели"с полным объяснением, а это:

 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();
 }

Не все так просто, но правильно и переносимо ...

0 голосов
/ 22 июля 2011

Я попробовал следующее, что действительно избегает круговой проблемы, и поэтому это неправильно в контексте (и требует приведения);хотя, если вам не нужно быть действительно круглым или строгим, это работает

#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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...