Get address of a function inside of the function in C/C++?

I was trying to return the address of a function which i called, something like :

void * myfunctionname(some parameters) {
  //some codes
  //more codes.
  return &myfunctionname;
}

How to replace void * by the right type to have the right signature ?

Upvotes: 1

Views: 1249

Answers (2)

arfneto
arfneto

Reputation: 1765

May be easier to read if you enclose "some parameters" in a struct with a pointer to your function, as in

typedef struct some_parameters
{
    int a;
    int b;
    struct some_parameters*
        (*my_function_name)(struct some_parameters*);
}   Some_parm;

In this way you write your function as

Some_parm* my_function_name(Some_parm* parm)
{
    // some codes
    // more codes
    // yet more code
    printf("F(): a = %d, b = %d\n", parm->a, parm->b);
    parm->a += 1;
    parm->b += 1;
    parm->my_function_name = my_function_name;
    return parm;
};

And write code like this

    Some_parm sp;
    sp.a = 10;
    sp.b = 20;
    sp.my_function_name = NULL;
    my_function_name(&sp); // call function directly
    printf("main(): a = %d, b = %d\n", sp.a, sp.b);
    sp.my_function_name(&sp); // call function from inside sp
    printf("main(): a = %d, b = %d\n", sp.a, sp.b);
    sp.my_function_name(&sp);
    printf("main(): a = %d, b = %d\n", sp.a, sp.b);
    my_function_name(&sp);
    printf("main(): a = %d, b = %d\n", sp.a, sp.b);

But you can write a typedef:

typedef void* (*pF_fii)
    ( void* (*)(void*, int, int), int, int );

Replacing the 2 int by your parameters. And declare just the function like this

pF_fii my_other_function(pF_fii one, int a, int b)
{    
    // some codes
    // more codes
    // yet more code
    printf("[function] a = %d, b = %d\n", a, b);
    return (pF_fii)&my_other_function;
};

This is the output

F(): a = 10, b = 20
main(): a = 11, b = 21
F(): a = 11, b = 21
main(): a = 12, b = 22
F(): a = 12, b = 22
main(): a = 13, b = 23
F(): a = 13, b = 23
main(): a = 14, b = 24

Using just the function

[function] a = 2, b = 3
[function] a = 4, b = 5

of this program

#include <stdio.h>

typedef void* (*pF_fii)
    ( void* (*)(void*, int, int), int, int );

pF_fii my_other_function(pF_fii one, int a, int b)
{    
    // some codes
    // more codes
    // yet more code
    printf("[function] a = %d, b = %d\n", a, b);
    return (pF_fii)&my_other_function;
};

typedef struct some_parameters
{
    int a;
    int b;
    struct some_parameters*
        (*my_function_name)(struct some_parameters*);
}   Some_parm;

Some_parm* my_function_name(Some_parm* parm)
{
    // some codes
    // more codes
    // yet more code
    printf("F(): a = %d, b = %d\n", parm->a, parm->b);
    parm->a += 1;
    parm->b += 1;
    parm->my_function_name = my_function_name;
    return parm;
};


int main(void)
{
    Some_parm sp;
    sp.a = 10;
    sp.b = 20;
    sp.my_function_name = NULL;
    my_function_name(&sp); // call function directly
    printf("main(): a = %d, b = %d\n", sp.a, sp.b);
    sp.my_function_name(&sp); // call function from inside sp
    printf("main(): a = %d, b = %d\n", sp.a, sp.b);
    sp.my_function_name(&sp);
    printf("main(): a = %d, b = %d\n", sp.a, sp.b);
    my_function_name(&sp);
    printf("main(): a = %d, b = %d\n", sp.a, sp.b);

    // using stand-alone function
    printf("\nUsing just the function\n\n");
    pF_fii another_f = NULL;
    another_f = my_other_function(another_f, 2, 3);
    another_f = my_other_function(another_f, 4, 5);

    return 0;
};```

Upvotes: 1

bruno
bruno

Reputation: 32586

The problem is to have the right return type, and it is 'recursive' because it contains itself.

As I know the only way to have a 'recursive' type is to use a struct or union, so

struct SFunc
{
  struct SFunc (*pf)(int param);
};

struct SFunc myfunctionname(int param)
{
  struct SFunc s;
  
  s.pf = myfunctionname;
  return s;
}

or

union UFunc
{
  union UFunc (*pf)(int param);
};

union UFunc myfunctionname(int param)
{
  union UFunc u;
  
  u.pf = myfunctionname;
  return u;
}

Compilations (same for both ways) :

pi@raspberrypi:/tmp $ gcc -c -Wall -pedantic cc.c
pi@raspberrypi:/tmp $ g++ -c -Wall -pedantic cc.cc
pi@raspberrypi:/tmp $ 

Upvotes: 6

Related Questions