0

I have written some code for calling nested functions using callback. But i am not getting output as I expected.

Please have look into code:

#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;
}

I have also tried with function pointer but in that also i am getting the same output as above.

cdhowie
  • 158,093
  • 24
  • 286
  • 300
ajayg2808
  • 375
  • 2
  • 10
  • 1
    `pair` tries to use `a` and `b` which no longer exist. They're not captured, are they? – ikegami Aug 02 '20 at 19:33
  • 1
    C has no concept of *closures*, or facilities for using them. You need to "fix" `a` and `b` some other way – pmg Aug 02 '20 at 19:33
  • 2
    Please don't tag questions about C as C++. They are not the same language. (In C++ this would be trivially handled using a lambda or a functor, neither of which are solutions that work in C.) – cdhowie Aug 02 '20 at 19:33
  • in general, the C language does not allow nested functions (although `gcc` does have such an extension)` Strongly suggest elimination of the 'nesting' of the functions – user3629249 Aug 03 '20 at 16:05

2 Answers2

1

Try this (maybe move functions and variables related to the closure to their own file):

#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;
}

Note that pair() is not reentrant, nor can you call it with different values for PairA and/or PairB at the same time.

pmg
  • 106,608
  • 13
  • 126
  • 198
  • 1
    Your anwer is worked fine. Thanks for your support. I have use global variable concept from your code into my original code, and it is working fine. – ajayg2808 Aug 03 '20 at 06:44
1

C doesn't support nested function, but a GCC extension does. The docs say:

If you try to call the nested function through its address after the containing function exits, all hell breaks loose.

pair tries to use a and b which no longer exist. GCC might provide nested functions, but they don't provide closures. This means the values of a and b aren't captured by the function; it's merely an address being returned by cons.

ikegami
  • 367,544
  • 15
  • 269
  • 518