0

I'm working with C, and I'm trying to build a kind of "composite" function, by joining 2 functions with the same signature, and a third with almost the same signature but just one less argument. The functions should be executed in sequence, but the final function must have the same signature. You can think it as building a function with code blocks using same signature(I have it implemented in C++ with policy class, but I'm trying a C approach as the rest of the code is in C already).

I built some code very simple, just to explain my approach.

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

typedef void simulFileProc(int a, int b);
typedef void simulRead(int a);
typedef struct compFunct{
    simulFileProc* file1;
    simulRead* read;
    simulFileProc* file2;
} compFunct;

void realProc(int a, int b){
    printf("call from realProc %d, %d\n",a,b);
}

void realRead(int a){
    printf("call from read %d\n",a);
}

simulFileProc* join(int a, int b, compFunct* func){
    
    void sf(int a, int b){
        func->file1(a,b);
        printf("intermediate line\n");
        func->read(a);
        func->file2(a,b);
    } 
    return &sf;
}

int main() {
    
    compFunct* c = malloc(sizeof(256));
    c->file1 = &realProc;
    c->read = &realRead;
    c->file2 = &realProc;
    int a=0;
    int b=0;
    
simulFileProc* s = join(a,b,c);
s(4,3);
    
    return 0;
}

It is working, but for some reason, just the first function print.

call from realProc 4, 3
intermediate line

If I comment the line "func->read(a);", I have a segmentation fault.

What is wrong ?? Is there a smarter way to do ?

Rod Bell
  • 23
  • 3
  • Your `sf` function is on the stack, and you return the address to it. So that address is pointing to something on the stack which is unreliable after the function returns. – user2740650 Oct 24 '20 at 17:43
  • 3
    No, C does not have [closures](https://en.wikipedia.org/wiki/Closure_(computer_programming)). Your function `sf()` exists and is treated just as any other function even though it was "defined inside" `join()`... The compiler behaves just as if it was outside (*except maybe for scope*). – pmg Oct 24 '20 at 17:45
  • The first function worked because the stack *happened* to contain `sf` still, but calling any function will wipe out that stack. – user2740650 Oct 24 '20 at 17:46
  • I think [function pointers](https://beginnersbook.com/2014/01/c-function-pointers/), or [ellipsis](https://stackoverflow.com/questions/3792761/what-is-ellipsis-operator-in-c), or a combination of the two may be something to look at. – ryyker Oct 24 '20 at 17:47
  • You migth like the thread [Is there a a way to achieve closures in C](https://stackoverflow.com/questions/4393716/is-there-a-a-way-to-achieve-closures-in-c) – pmg Oct 24 '20 at 17:51
  • 1
    This line of code allocates sizeof(int), not 256 bytes or sizeof(compFunct): `compFunct* c = malloc(sizeof(256));`. Not sure what you were trying to achieve there. – jwdonahue Oct 24 '20 at 18:16
  • I'm sure with some dark wizardry you can do this in C, but the more conventional approach is to avoid it and seek a more C-like solution such as a simple wrapper function. – tadman Oct 24 '20 at 19:03
  • The (main) problem is `compFunct* c = malloc(sizeof(256));`. It should be `compFunct *c = malloc(sizeof(compFunct));`. – CristiFati Oct 25 '20 at 17:05

0 Answers0