Definir una función que devuelve un puntero de función que también devuelve un puntero de función sin typedefs




function function-pointers (3)

El tipo de retorno de la función get_pfn es -

void (*) ();

Entonces, el tipo de &get_pfn es -

void (*(*)(int))()

Ahora, esta función devuelve este tipo, por lo tanto, su firma será:

void (*(*(foo)())(int))()

Puede verificar esto escribiendo esto en cdecl.org

Estoy tratando de entender realmente los punteros de función sin usar typedef pero parece que no puedo entender esto. No entiendo qué firma se necesita para transmitir que devuelvo un puntero a un puntero a una función.

#include <stdio.h>

void odd()  { printf("odd!\n");  }
void even() { printf("even!\n"); }

void (*get_pfn(int i))()
{
    return i % 2 == 0 ? &even : &odd;
}

__SIGNATURE__
{
    return &get_pfn;
}

int main()
{
    get_pfn_pfn()(1)();
    get_pfn_pfn()(2)();
    return 0;
}

Para que esto funcione, ¿ __SIGNATURE__ tiene que ser __SIGNATURE__ ?


Los punteros de función sin typedef pueden ser difíciles de trabajar. Para resolverlos, trabajas de adentro hacia afuera.

Analicemos exactamente cómo encontramos la firma de función correcta.

get_pfn_pfn es una función:

get_pfn_pfn()

Que no tiene parámetros:

get_pfn_pfn(void)

Y devuelve un puntero:

*get_pfn_pfn(void)

A una función:

(*get_pfn_pfn(void))()

Que toma un parámetro int :

(*get_pfn_pfn(void))(int)

Y devuelve un puntero:

*(*get_pfn_pfn(void))(int)

A una función:

(*(*get_pfn_pfn(void))(int))()

Que no tiene parámetros:

(*(*get_pfn_pfn(void))(int))(void)

Y no devuelve nada (es decir, void ):

void (*(*get_pfn_pfn(void))(int))(void)

Por supuesto, usar typedef 's simplifica esto enormemente.

Primero el tipo para even e odd :

typedef void (*func1)(void);

Lo que luego podemos aplicar a get_pfn :

func1 get_pfn(int) { ... }

Entonces el tipo para esta función:

typedef func1 (*func2)(int);

Lo que podemos aplicar a get_pfn_pfn :

func2 get_pfn_pfn(void) { ... }

es por aquí:

void (*(*get_pfn_pfn(void))(int))()




function-pointers