简体   繁体   English

谁能向我解释这个输出?

[英]Can anyone explain this output to me?

So I was playing around with some thought experiments where I imagined what would happen when two functions became mutually recursive. 因此,我在进行一些思想实验,我想象两个函数相互递归时会发生什么。 One such one was what if both functions could potentially fall into an infinite loop. 如果两个函数都可能陷入无限循环,那将是一个这样的例子。

To that end, I thought up of this simple example: 为此,我想到了一个简单的示例:

#include <iostream>
#include <cstdlib>

int foo(int x);
int bar(int x);


int foo(int x)
{
    return bar(x + 1);
}

int bar(int x)
{
    return foo(x - 1);
}

int main(int argc, char **argv)
{
    if (argc > 1)
        std::cout << "The value is: " << foo(atoi(argv[1])) << std::endl;

    return 0;
}

Interestingly, this will actually print out absolutely nothing if you compile it with g++. 有趣的是,如果使用g ++进行编译,则实际上不会打印任何内容。 Compile it with any -O switch and it falls into an infinite loop. 使用任何-O开关对其进行编译,它将陷入无限循环。

Thoughts? 思考? Is this potentially a compiler bug, or is this to be expected? 这可能是编译器错误,还是可以预期的? I'd think in the case of -O optimizations, it would realize that foo(x) and bar(x) return just x. 我认为在-O优化的情况下,它将意识到foo(x)和bar(x)仅返回x。

I didn't expect it to actually "optimize away" the call and completely ignore printing out "The value is" to standard input. 我没想到它实际上会“优化”该调用,而完全忽略了将“值是”打印到标准输入中。

Edit: I compiled this as just g++ source.cpp (-O1/2/3), under Cygwin using GCC 4.5.0. 编辑:我使用GCC 4.5.0在Cygwin下将其编译为g ++ source.cpp(-O1 / 2/3)。 The -OX versions actually loop infinitely without the stack overflowing. -OX版本实际上无限循环而不会导致堆栈溢出。

Since you didn't specify which C++ you're on about I'll give the C++0x answer: 由于您未指定要使用的C ++,因此我将给出C ++ 0x答案:

This is in fact undefined behaviour in C++0x . 实际上, 这是 C ++ 0x中未定义的行为

I can't fully explain the behaviour if you're using C++03, but since your stack will eventually overflow, you're still really within the realm of implementation-dependent behaviour. 如果您使用的是C ++ 03,我无法完全解释其行为,但是由于您的堆栈最终将溢出,因此您仍然处在与实现相关的行为的范围之内。 Expecting anything sane to happen here is a fool's errand. 期望这里发生任何理智的事情都是傻子的事。

From a mathematical point of view, f(x) = b(x + 1) and b(x) = f(x - 1) are not sufficient to define f and b . 数学观点来看, f(x)= b(x +1)b(x)= f(x-1)不足以定义fb One possible solution is f(x) = x and b(x) = x - 1 , while another one is f(x) = 0 and g(x) = 0 (and there are infinitely many more ways). 一个可能的解决方案是f(x)= xb(x)= x-1 ,而另一个解决方案是f(x)= 0g(x)= 0 (并且还有更多种方法)。 So mathematically, the question of what the function should return doesn't have an answer. 因此,从数学上讲,该函数应返回什么的问题没有答案。 From a computational point of view, the situation is even worse, because after all, you are not defining mathematical functions, you are specifying how a computation is to be performed. 计算的角度来看,情况甚至更糟,因为毕竟您没有定义数学函数,而是要指定如何执行计算。 foo(x - 1) means "perform the computations specified in the function foo() when we pass the value of x - 1 as a parameter", and similarly for bar(x + 1) . foo(x - 1)意思是“当我们将x - 1的值作为参数传递时,执行在foo()函数中指定的计算”,并且类似地对于bar(x + 1) So when each function says, unconditionally, that the other function is to be called, you have specified that you wish for an infinite recursion to take place. 因此,当每个函数无条件地说要调用另一个函数时,您已指定希望进行无限递归。 As others have mentioned, some languages (or language versions) treat this as a well-defined situation (where the desired outcome is that the program hangs), while others treat it as an undefined situation (ie, the compiler may do anything it likes). 正如其他人提到的那样,某些语言(或语言版本)将此视为良好定义的情况(期望的结果是程序挂起),而另一些语言则将其视为未定义的情况(即,编译器可能会做任何喜欢的事情)。

As your recursion has no stopping condition it is only natural that you get into an infinite loop. 由于递归没有停止条件,因此自然会陷入无限循环。 Your assumption, that these functions return "just x" is false. 您假设这些函数返回“ just x”是错误的。 They are bound to never return. 他们注定永远不会回来。

The compiler cannot just optimize away recursion. 编译器不能仅仅优化递归。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM