C 中链接函数指针和递归时的模糊行为

问题描述 投票:0回答:2

我在 C 项目中偶然发现了一些严重令人头疼的行为,并且我开始怀疑我是否遇到了某些编译器或语言特定的限制。这是我正在做的事情的简化版本:

#include <stdio.h>

typedef void (*callback_t)(callback_t);

void recursive_func(callback_t next_call) {

    printf("Function iteration...\n");

    if (next_call) {
        next_call(next_call);  // The crux of the issue
    }
}

int main() {

    void first_call(callback_t c) { recursive_func(c); } 
    void second_call(callback_t c) { recursive_func(c); }
    void third_call(callback_t c) { recursive_func(c); } 

    first_call(second_call);  // Start the chain

    return 0;
}

理论上,这应该会产生一个整齐的递归链:first_call -> secondary_call ->third_call -> recursive_func,并使用“Function iteration...”消息循环几次。然而我不是。

这段代码是否根据 C 标准调用了未定义的行为?让我怀疑的是 recursive_func 中的自引用回调。

这是否超出了涉及指针的嵌套函数调用的某些特定于编译器的限制?

是否有更优雅或符合标准的方法来使用 C 中的函数指针实现类似的链式递归?

我对这个特定示例的解决方法不太感兴趣,而更感兴趣的是了解此处可能暴露的 C 的基本限制。

如果您遇到过类似的事情或者对 C 函数指针处理的深度有深入的了解,请告诉我!

c recursion
2个回答
0
投票

你告诉first_call调用second_call,但是你用

next_call(next_call)
将second_call传递给它自己,所以second_call之后会无限地调用它自己。

顺便说一句,在文献中这种技术被称为“连续传递”,如果你搜索这个,你应该会找到很多有用的信息。


0
投票

让我们手动取消递归:

first_call(second_call) ->  
recursive_func(second_call) -> 
second_call(second_call) -> 
recursive_func(second_call) -> 
second_call(second_call)

所以如你所见,它只会迭代

second_call
。目前尚不清楚为什么您相信它会以某种方式知道如何调用
third_call
,因为在您的代码中它没有在任何地方被引用。

© www.soinside.com 2019 - 2024. All rights reserved.