如何检查函数是否正在回调自身

How to check if a function is calling back to itself

假设我们在库中有一个 C 函数 funA,在 funA 内部它会调用一些其他函数 funB、funC 等。 funB 和 funC 可能会回调 funA。所以问题是: 是否可以在 funA 内部检测到这种情况,例如:

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

}

结论

如果是单次调用,可以在调用一次这个函数的时候设置一个global/static标志,在开始的时候检查一下。或者为了取消单次调用的限制,您可以在函数返回之前重置此标志。 类似的东西:

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

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

    used = false;
}

注意 - 这不适用于多线程 - 此函数不可重入..

这可以通过静态标志来完成。

调用该函数时,如果未设置标志,则设置它并继续,否则立即return。然后在函数结束时,清除标志以便再次输入。

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

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

如果这需要在多线程中单独工作,您可以将变量声明为 _Thread_local 而不是 static

通过间接级别,您甚至可以计算函数被调用的次数:

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

这样,它是完全线程安全的。如果您不想传递包装函数或参数,则可以使用 thread-specific storage.

也许您可以通过另一种方法识别来电者:

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