0

With reference to the following code:

#include <cstdint>

void func() {
    return;
}

void funcparent() {
    uint64_t h = 99;
    func();
}

void funcparent2() {
    func();
}

void funcparent3() {
    func();
    int h = 99;
}

And assembly, from compiling with no optimization with recent clang for a non-Windows calling convention, like on Godbolt:

_Z4funcv:                               # @_Z4funcv
        push    rbp
        mov     rbp, rsp
        pop     rbp
        ret
_Z10funcparentv:                        # @_Z10funcparentv
        push    rbp
        mov     rbp, rsp
        sub     rsp, 16
        mov     qword ptr [rbp - 8], 99
        call    _Z4funcv
        add     rsp, 16
        pop     rbp
        ret
_Z11funcparent2v:                       # @_Z11funcparent2v
        push    rbp
        mov     rbp, rsp
        call    _Z4funcv
        pop     rbp
        ret
_Z11funcparent3v:                       # @_Z11funcparent3v
        push    rbp
        mov     rbp, rsp
        sub     rsp, 16
        call    _Z4funcv
        mov     dword ptr [rbp - 4], 99
        add     rsp, 16
        pop     rbp
        ret

Where is there a sub rsp, 16 (and subsequent add) in funcparent() and funcparent3()? I thought there is something to do with allocating the stack but funcparent2() makes me think otherwise.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
PYA
  • 8,096
  • 3
  • 21
  • 38
  • https://stackoverflow.com/questions/67176276/too-large-overaligned-stack-frame-with-gcc-but-not-with-clang. It's lowering the stack frame...though I'm not sure why, either, seeing that the stack grows downwards. – user1280483 Dec 19 '21 at 01:48
  • 4
    It is reserving space for the local variable `h`. – Raymond Chen Dec 19 '21 at 02:18
  • @RaymondChen 16 bytes for `h`? and why does it have to incase of the variable being declared before and after the function call? – PYA Dec 19 '21 at 03:11
  • @user1280483 yeah I understand it is lowering it, but dont know why... – PYA Dec 19 '21 at 03:22
  • 3
    It adjusts the stack pointer by 16 so that the stack remains 16-byte aligned. – prl Dec 19 '21 at 03:47
  • 1
    This is unoptimized code, so the compiler always allocates stack space for all local variables. – prl Dec 19 '21 at 03:48
  • @prl why for `funcparent3` ? the variable is declared after the function call (I might be missing something very basic) – PYA Dec 19 '21 at 04:22
  • @PYA the compiler is allowed to allocate variables anywhere it wants – phuclv Dec 19 '21 at 04:28
  • @phuclv i don't quite follow. Is there any way to force the compiler to allocate the variable AFTER the function call? in other words, if the compiler allocates the variable after the function call, the `sub` is not needed like in `funcparent2`? – PYA Dec 19 '21 at 04:37
  • 1
    @PYA why should it allocate after the function call? Typically each stack frame is set up at the beginning only, and both the function and the variable are in the same scope so the variable should be allocated when the stack frame is entered – phuclv Dec 19 '21 at 04:40
  • 1
    @phuclv I see.. but why 16 bytes? if i add another `int` after 'h' it still has a `16` so i am not sure how that relates to allocation – PYA Dec 19 '21 at 04:44
  • it's for 16-byte alignment before any function calls as @prl said. Please read the [System V AMD64 calling convention to see](https://en.wikipedia.org/wiki/X86_calling_conventions#System_V_AMD64_ABI). That allows easier mixing SSE code – phuclv Dec 19 '21 at 04:54
  • 1
    In unoptimized code, the compiler allocates space for all the local variables in the function at the beginning of the function. Is there a way to get it to do it differently? Yes, enable optimization. Looking at unoptimized compiler output is generally pretty pointless. – prl Dec 19 '21 at 08:20

0 Answers0