Program returns a value of -1073741571 instead of going forever

1

i'm learning about functions and decided to make a loop where two function(in this case funcA and funcB ) call each other forever but it stops execution after some time. The code looks like this:

#include <iostream>

void funcA(); //forward declaration

//funcB calls funcA 
void funcB()
{
    funcA();
}

//funcA prints 1 and calls funcB again 
void funcA()
{
    std::cout<<1;
    funcB();
}

//main calls funcB
int main()
{
    funcB();
    return 0;
}  

the returned value is -1073741571 (0xC00000FD). can you expain why this happens?

c++
stack-overflow
iostream
mutual-recursion
asked on Stack Overflow Jul 31, 2019 by Rcheul4 • edited Aug 23, 2019 by templatetypedef

3 Answers

4

Whenever you call a function, the program reserved a small amount of space to hold information for that function (space for local variables, information about where to return to after the function exits, etc.). This memory is allocated from a region called the call stack (or “stack” for short), and it’s returned to the stack when the function finishes running.

The stack typically has a fixed, small size. If you have a very long chain of calls (usually measured in tens of thousands of calls), you can run out of stack space and the program will terminate with an error called a stack overflow. That’s what’s happening in your program.

Generally speaking, if you have recursive (or in your case, mutually recursive) functions, you’ll need to make sure that the recursion depth doesn’t get “too large” for some definition of “too large,” or this sort of thing can happen. There are some special cases where some compilers can recognize that you’re writing recursive code and transform it into code that doesn’t allocate multiple stack frames (see “tail-call elimination” for more details), but that’s the exception rather than the rule.

answered on Stack Overflow Jul 31, 2019 by templatetypedef
4

Ok so since this is gcc on Windows 10 take a look on this goodbolt

Without any optimization enabled both functions are explicitly called.

b():
        push    rbp
        mov     rbp, rsp
        call    foo()
        call    a()
        nop
        pop     rbp
        ret
a():
        push    rbp
        mov     rbp, rsp
        call    b()
        nop
        pop     rbp
        ret

As other answer point out each call leaves on stack information how to come back to function which called function. Now since functions never return this information is never removed from stack, but is constantly added. As a result you have got stack overflow which on Windows is indicated by value 0xC00000FD.

Now if you enable optimization (-O2) compiler is able to figure out this is infinitive loop (using technique called tail recursion).

b():
        sub     rsp, 8
.L2:
        call    foo()
        jmp     .L2
a():
        sub     rsp, 8
.L6:
        call    foo()
        jmp     .L6

So with optimization enabled you will have infinitive loop as you are expecting.

answered on Stack Overflow Jul 31, 2019 by Marek R
3

While in theory this goes on forever the problem is that every time a function is called some memory needs to be reserved on something called the 'stack'. Eventually there is no more space left on that 'stack' and you get a StackOverflowException. 0xC00000FD is the error code windows uses to tell you that a StackOverflowException happened

answered on Stack Overflow Jul 31, 2019 by Cromon • edited Jul 31, 2019 by Guillaume Racicot

User contributions licensed under CC BY-SA 3.0