Compilers are free to organize stack frames (provided they even use stacks) in any way.
They can do this for alignment reasons or for performance reasons or for no reason. It would be unreasonable to suggest any particular order.
If you did not invoke undefined behavior by overflowing the buffer, you probably would never know how it should be.
The compiler can not only regroup its variables, but also optimize them from existence, if he can establish that they are not used. With code:
#include <stdio.h> int main (void) { char bing[71]; int x = 7; bing[0] = 11; return 0; }
Compare normal assembler output:
main: pushl %ebp movl %esp, %ebp andl $-16, %esp subl $80, %esp movl %gs:20, %eax movl %eax, 76(%esp) xorl %eax, %eax movl $7, (%esp) movb $11, 5(%esp) movl $0, %eax movl 76(%esp), %edx xorl %gs:20, %edx je .L3 call __stack_chk_fail .L3: leave ret
with insanely optimized:
main: pushl %ebp xorl %eax, %eax movl %esp, %ebp popl %ebp ret
Pay attention to something missing in the latter? Yes, there is no stack manipulation to create space for bing or x . They do not exist. In fact, the whole sequence of code comes down to the following:
- set the return code to 0.
- return.
source share