从相同地址使用相同数据调用的函数是否总是无限递归?

问题描述

#define ptr uintptr_t 

void X(ptr P,ptr I)
{
  ((void(*)(ptr))P)(I);
}

void Y(ptr P) 
{
  X(P,P); 
} 


int main() 
{   
  Y((ptr)Y);  
}

我正在用 C 语言做计算机科学,因为计算机科学家不这样做,所以我来这里是为了寻求更多实际帮助。我需要具体研究计算机科学(使用 C 和 x86 机器语言),因为抽象会泄露关键细节。

对其机器语言的执行跟踪证明,上述函数在相同的机器地址和相同的输入数据中至少被依次调用了两次。

有没有反例,一个函数从同一个机器地址和相同的输入被依次调用两次**,但不是无限递归的?

** 中间可以有任何中间代码
(除了函数从被调用函数返回到同一个调用者)。

解决方法

来自上面的讨论:
调用函数不访问静态或全局数据作为终止其函数调用序列的基础已被重新解释为如下所示的 (3) 的第一部分。 (3) 的第二部分基于对此答案的评论。

如果函数Y()调用的函数X()的执行轨迹显示:
(1) 函数X()从Y()的同一机器地址依次调用两次。
(2) 与 X() 的参数相同。
(3) Y()中没有条件分支或索引跳转指令。
(4) 没有函数调用从 X() 返回到 Y().
那么从 Y() 到 X() 的函数调用是无限递归的。

如果有人不同意,请在评论中告诉我,我会更新这个答案。

,

扩展原始答案以涵盖模拟:

#define ptr uintptr_t 

void X(ptr P,ptr I)
{
  Simulate(P,I);
}
        
void Y(ptr P) 
{
  X(P,P); 
} 
                    
int main() 
{   
  Y((ptr)Y);  
}

如果函数Y()调用的函数X()的执行轨迹显示:
(1) 函数X()从Y()的同一机器地址依次调用两次。
(2) 与 X() 的参数相同。
(3) Y()中没有条件分支或索引跳转指令。
(4) 没有函数调用从 X() 返回到 Y().
那么从Y()到X()的函数调用就是无限嵌套模拟。

在无限嵌套模拟的情况下,总是满足规则 (4),因为没有模拟器每次都返回到它正在模拟的输入。

当 X() 模拟 Y() 的机器语言并在模拟 Y() 的每条机器指令后检查结果执行轨迹时,X() 可以应用上面提供的标准停止模拟 Y(),因为 Y () 指定无限嵌套模拟。