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?
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.
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.
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
User contributions licensed under CC BY-SA 3.0