1

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 ?

bruno
  • 32,421
  • 7
  • 25
  • 37
  • A function pointer can not be converted to a `void *`. See https://stackoverflow.com/a/26917282/5567382 that answers for both C and C++. – Thomas Jager Aug 13 '20 at 12:54
  • 1
    What would you _do_ with the address of the function, though? – Botje Aug 13 '20 at 12:57
  • 1
    I don't understand what you mean. `&myfunctionname` _is_ the address of the function. It's not clear why you can't use that or what you are trying to do. – Lundin Aug 13 '20 at 13:00
  • 2
    In C you can use the address of a function inside the function, and even return it. Your example "just" has the wrong return type. – the busybee Aug 13 '20 at 13:02
  • I want to learn how can i return the information and what type it should be? @the busybee – Türker Berke Yıldırım Aug 13 '20 at 13:03
  • 2
    What exactly are you planning to do with the address of the function? What problem does having this address solve? – dbush Aug 13 '20 at 13:06
  • We are designin a ThreadCore for thread management system in Session Border Controller and this information will be needed we guess. – Türker Berke Yıldırım Aug 13 '20 at 13:08
  • 2
    For what purpose? To find out who created a thread, or to find out which thread callback you are inside, or...? – Lundin Aug 13 '20 at 13:13
  • 2
    @TürkerBerkeYıldırım You should be returning a function pointer, not a `void *`. – Thomas Jager Aug 13 '20 at 13:15
  • @TürkerBerkeYıldırım if I well understand your problem is not to get the address (because `&func`is enough) but to have the right return type, isn't it ? – bruno Aug 13 '20 at 13:19
  • Yes i want to back the right type of the return value, and also yes the "lundin's" question. I will track who create the thread and i will send signal for get the address data from threads – Türker Berke Yıldırım Aug 13 '20 at 13:25
  • 1
    @bruno You can convert a function pointer to another function pointer type, and back without changing it's value. You have to convert it back to the actual function's type externally, but as long as you don't call it as the wrong type, it's safe. – Thomas Jager Aug 13 '20 at 13:26
  • So it will look like this one ; void (*func2(int threadno, void (*func )(int)))(int); – Türker Berke Yıldırım Aug 13 '20 at 13:28
  • 1
    @ThomasJager the goal is to have the right type without using any cast everywhere, can you look at my answer ? – bruno Aug 13 '20 at 13:31
  • 1
    What's the point of a function that returns its own address? **To call the function in the first place you have to already know its address.** – Andrew Henle Aug 13 '20 at 13:34
  • A similar question was discussed in C Programming FAQ, [Question 1.22](http://c-faq.com/decl/recurfuncp.html), long ago. – M. Nejat Aydin Aug 13 '20 at 16:37

2 Answers2

6

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 $ 
bruno
  • 32,421
  • 7
  • 25
  • 37
  • 2
    @TürkerBerkeYıldırım your question is very interesting, I never had that case. I think you have to make your question more clear, the problem is not to get the address but to have the right return type for the function returning itself – bruno Aug 13 '20 at 13:36
  • How should i edit the question? Have you got any suggestion – Türker Berke Yıldırım Aug 13 '20 at 13:40
  • @TürkerBerkeYıldırım I edited your question, if you disagree with me say me or revert my edition – bruno Aug 13 '20 at 13:45
1

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

arfneto
  • 1,227
  • 1
  • 6
  • 13