为什么在没有显式return语句的情况下递归的return调用会中断堆栈? [英] Why does a recursed return call break out of stack without an explicit return statement?

查看:135
本文介绍了为什么在没有显式return语句的情况下递归的return调用会中断堆栈?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

向我展示了一个示例程序来演示递归,该递归看起来似乎不起作用,但应该起作用。逻辑很清楚,但是即使没有返回递归函数调用,为什么它仍然起作用?似乎 return 命令即使没有被请求也会中断。这是语言标准还是gcc?我在Windows和Linux上使用gcc编译的C和C ++看到了它。

I was shown a sample program to demonstrate recursion which looks like it should not work but does. The logic is pretty clear but why does it work even when the recursed function call is not returned? It seems like the return command breaks out of the stack even if it isn't requested to. Is this a language standard or a gcc thing? I saw it with C and C++ compiled with gcc on Windows and Linux.

#include <iostream>
#include <cstdlib>

using namespace std;

int isprime(int num, int i)
{
   if (i == 1) {
      return 1;
   }
   else {
      if (num % i == 0)
         return 0;
      else
         isprime(num, i-1); // should be returned
   }
}


int main(int argc, char** argv)
{
   int input = atoi(argv[1]);
   cout << input << "\t" << isprime(input, input/2) << "\n";
}


推荐答案

偶然地,返回值恰好在调用者期望的寄存器中。仅当编译器将其实现为递归函数时,此方法才有效。从技术上讲,使用不提供功能的函数的返回值这是未定义的行为

Things like that only work if accidentally the return value happens to be in the register where the caller expects it. This only works if this is realized by your compiler as a recursive function. Technically it is undefined behavior to use the return value of a function that doesn't provide one.

编辑:在现代架构上,函数的返回值(可能的值)在特定的硬件寄存器中传递。递归调用函数时,在所有情况下,硬件寄存器都在底部设置为期望值。如果偶然地从递归弹出窗口时,硬件寄存器从未更改,那么您将得到正确的值。

On modern architectures the return value of a function for values for which it is possible is passed in a specific hardware register. When you call your function recursively, on the bottom in all cases that hardware register is set to the expect value. If by chance when popping up from recursion that hardware register is never changed, you end up with the correct value.

如果返回,则所有此模式均不起作用

All of this pattern wouldn't work, if the return value would be placed at some location of the stacks of the (recursive) callers.

在任何情况下,所有这些都应由任何现代编译器捕获,并为您提供一个警告。如果不是这样,则说明您没有好的编译器,或者您在使用过于防御的命令行选项。

In any case, all of that should be captured by any modern compiler and give you a warning. If it doesn't you don't have a good compiler, or you are using too defensive command line options.

除夕特别节目:在现实世界中,这样的代码(带有 return )甚至不会被实现为递归函数。只需花费很少的精力,您就可以找到该函数的迭代变体,并且如果您要求最大程度的优化,任何现代的体面的编译器都应该能够找到它。

New year's eve special: In the real world, code like this (with the return) wouldn't even be realized as a recursive function. With not too much effort you will find an iterative variant of that function, and any modern decent compiler should be able to find it as well if you ask for maximal optimization.

这篇关于为什么在没有显式return语句的情况下递归的return调用会中断堆栈?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆