我在 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 函数指针处理的深度有深入的了解,请告诉我!
你告诉first_call调用second_call,但是你用
next_call(next_call)
将second_call传递给它自己,所以second_call之后会无限地调用它自己。
顺便说一句,在文献中这种技术被称为“连续传递”,如果你搜索这个,你应该会找到很多有用的信息。
让我们手动取消递归:
first_call(second_call) ->
recursive_func(second_call) ->
second_call(second_call) ->
recursive_func(second_call) ->
second_call(second_call)
所以如你所见,它只会迭代
second_call
。目前尚不清楚为什么您相信它会以某种方式知道如何调用 third_call
,因为在您的代码中它没有在任何地方被引用。