Bill Randerson
Bill Randerson

Reputation: 1088

How to check if a function is calling back to itself

Let's say we have a C function funA in a library, inside funA it'll call some other functions funB, funC, .etc. It's possible that funB and funC could call funA back. So the question is: Is it possible to detect this situation just inside funA, something like:

void funA(void) {
    if (...) {
         // Calling back to funA
    }

}

Conclusion

Upvotes: 2

Views: 74

Answers (4)

0___________
0___________

Reputation: 67820

maybe another approach you can identify the caller:

void func_a(void *ptr);
void func_b(void);
void func_c(void);

void func_a(void *caller)
{
    if(caller == func_a)
    {
        printf("called from func_a\n");
        return;
    }
    if(caller == func_b)
    {
        printf("called from func_b\n");
        return;
    }    
    if(caller == func_c)
    {
        printf("called from func_c\n");
        return;
    }    
    if(caller == NULL)
    {
        printf("called from somewhere elese - going to call myself\n");
        func_a(func_a);
    }
}

void func_b()
{
    func_a(func_b);
}

void func_c()
{
    func_a(func_c);
}

int main()
{
    func_b();
    func_c();
    func_a(NULL);

    return 0;
}

Upvotes: 1

Andrew Henle
Andrew Henle

Reputation: 1

With a level of indirection, you can even count the number of times your function has been called:

void func( int count )
{
    printf( "Count is %d\n", count );
    if ( ... ) // no longer want to recurse...
    {
        return;
    }
    func( count + 1 );
}

// wrap the actual recursive call to hide the parameter
void funA()
{
    func( 0 );
}

This way, it's fully thread-safe. If you don't want a wrapper function nor a parameter passed, you can use thread-specific storage.

Upvotes: 0

Eugene Sh.
Eugene Sh.

Reputation: 18381

If it is a single call only, you can have a global/static flag set once this function is called, and check it in the beginning. Or to remove the restriction of being single call, you can reset this flag before the function is returning. Something like that:

void funA(void) {
    static bool used = false;
    if (used)
    {
        printf("It is used!\n");
    }
    used = true;

    // .... Do stuff here, including possible recursion

    used = false;
}

Note - this won't work with multithreading - this function is not reentrant..

Upvotes: 2

dbush
dbush

Reputation: 224437

This can be done with a static flag.

When the function is called, if the flag is not set then set it and continue, otherwise return right away. Then at the end of the function, you clear the flag so you can enter it again.

void funcA(void) 
{
    static int callback = 0;

    if (callback) return;
    callback = 1;
    ...
    callback = 0;
}

If this needs to work in multiple thread separately you can declare the variable as _Thread_local instead of static.

Upvotes: 3

Related Questions