Compiler Explorer编译C++:有无return语句致参数栈位置差异原因探究
Great question! Let's unpack this behavior, which boils down to stack frame layout choices in debug-mode compilation (usually {-O0}, the default for Compiler Explorer when you don't specify optimizations) and how the compiler handles unused variables.
First, a Quick Recap of x86-64 Stack Frames
In -O0 mode, compilers set up a full stack frame using rbp (the base pointer) to make debugging easier—every local variable and spilled parameter has a fixed offset from rbp. The stack grows downward, so lower offsets from rbp (like rbp-4, rbp-8) correspond to memory addresses deeper in the stack.
What's Happening in Your Code
Let's break down the two scenarios:
1. With the return e; statement
When you include the return, the compiler treats e as a used variable (since it's the return value). It allocates 4 bytes of stack space for e at rbp-4. Then, since the stack needs to hold this variable, the spilled function parameters (copied from registers like edi, esi to the stack for debugging) have to start at the next available offset: rbp-8 for the first parameter a, rbp-12 for b, etc.
2. Without the return e; statement
Without the return, the compiler notices that e is never used (there's no code that reads its value). Even in -O0 mode, the compiler does minimal dead-code elimination for variables that serve no purpose, so it drops the stack allocation for e. Now the first available stack slot below rbp is rbp-4, so the spilled parameters start there instead of rbp-8.
Key Points to Note
- This is not a full compiler optimization (like what you'd see with
-O1or higher), but rather a pragmatic debug-mode adjustment to avoid wasting stack space on unused variables. - In optimized builds (e.g.,
-O1), the compiler would likely:- Skip setting up a full
rbpstack frame entirely (usingrspdirectly for stack access). - Not spill parameters to the stack at all (since it can keep them in registers for calculations).
- Even eliminate
dandeentirely if they're unused, since they don't affect the program's output.
- Skip setting up a full
- Also, remember that a non-void function without a
returnstatement is undefined behavior in C++—the compiler can generate any code it wants, but in this case, it's just making a sensible stack layout choice for the code it does generate.
内容的提问来源于stack exchange,提问作者WARhead

