Reputation: 21
Consider the following program:
fn recursive_call(x: u32) -> u32 {
println!("x: {:?}", x);
recursive_call(x +1)
}
fn main() {
recursive_call(0);
}
When I run cargo build && ./target/debug/recursive_call
, this crashes after x: 58152
:
x: 58152
thread 'main' has overflowed its stack
fatal runtime error: stack overflow
Aborted (core dumped)
while when I run cargo build --release && ./target/release/recursive_call
, this crashes only after x: 104728
:
x: 104728
thread 'main' has overflowed its stack
[...]
I wondering where this difference in behavior comes from? Is the stack size different in release vs. debug mode? Or is this because of some compile time optimizations I am missing (if so, what would so optimizations be?)
Upvotes: 2
Views: 1265
Reputation: 23244
The stack size is the same for debug and release (and unless you have threads, the stack size is actually fixed by the OS, see eg. ulimit -s
on Linux). However the stack usage may be different because in debug mode the compiler adds some data to each stack frame to help debuggers find local variables.
Note that tail-call optimization may cause the compiler to remove the recursion and allow an infinite loop in release mode.
Upvotes: 1
Reputation: 5320
Yep, according to Godbolt on x86-64 the reserved stacksize for the function in debug mode is 120 bytes, with optimizations turned on (-O
) it is 72 bytes. That is quite normal.
Upvotes: 3