Вложенная функция обратного вызова в C - PullRequest
0 голосов
/ 02 августа 2020

Я написал код для вызова вложенных функций с помощью обратного вызова. Но я не получаю результат, как я ожидал.

Пожалуйста, посмотрите код:

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

typedef int (*f_ptr)(int a, int b);
typedef int (*pair_ptr)(f_ptr);

pair_ptr cons(int a, int b)
{

    int pair(f_ptr f)
    {
        return (f)(a, b);
    }
    return pair;
}

int car(pair_ptr fun)
{
    int f(int a, int b)
    {
        return a;
    }
    return fun(f);
}

int main()
{
    int a = 3;
    int b = 4;
    // It should print value of 'a'
    printf("%d", car(cons(a, b)));     // Error : It is printing '0'
    return 0;
}

Я также пробовал использовать указатель на функцию, но и в этом я получаю то же самое вывод, как указано выше.

Ответы [ 2 ]

1 голос
/ 02 августа 2020

Попробуйте это (возможно, переместите функции и переменные, связанные с закрытием , в их собственный файл):

#include <stdio.h>

typedef int (*f_ptr)(int a, int b);
typedef int (*pair_ptr)(f_ptr);

static int PairA, PairB;
static void setPairA(int a) { PairA = a; }
static void setPairB(int b) { PairB = b; }

int f(int a, int b) {
    (void)b; // removed unused parameter warning
    return a;
}

int pair(f_ptr fp) {
    return fp(PairA, PairB);
}

pair_ptr cons(int a, int b) {
    setPairA(a);
    setPairB(b);
    return pair;
}

int car(pair_ptr fun) {
    return fun(f);
}

int main(void) {
    int a = 3;
    int b = 4;
    printf("%d\n", car(cons(a, b)));
    return 0;
}

Обратите внимание, что pair() не является реентерабельным, и вы не можете его называть с разными значениями для PairA и / или PairB одновременно.

0 голосов
/ 02 августа 2020

C не поддерживает вложенную функцию, но расширение G CC поддерживает. документы говорят:

Если вы попытаетесь вызвать вложенную функцию по ее адресу после выхода из содержащей ее функции, все развалится.

pair пытается использовать a и b, которых больше нет. G CC может предоставлять вложенные функции, но они не предоставляют закрытие . Это означает, что значения a и b не захватываются функцией; это просто адрес, возвращаемый cons.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...