Search code examples
c++assemblyx86-64calling-conventionabi

C++ What actually happens in assembly when you return a struct from a function?


I'm trying to figure out what actually happens in C++ if you return a struct by value from a function, vs. return a pointer to the struct. How is a struct communicated when its sent by value if a function can only return a value that can fit in a register? (I read that somewhere.)

I tried testing it on Godbolt to see what it's doing. But I don't understand the assembly so that was a bit optimistic of me.

It does look to me without much assembly knowledge that the function is just changing some memory that exists before the function is called? So then the concept of returning something from a function is just an abstraction and the function is just setting some bytes in a memory location that already exists and then end jumping back to main()? In which case nothing is copied at all and the return is "free"?

Godbolt: Return int

Godbolt: Return struct{int int int}


Solution

  • So I spent hours playing with Godbolt's Compiler Explorer and reading up until I figured out the practical answer.

    What I've gathered is this:

    1. If the value fits into a register, it's left in a register as the return value.
    2. If the value fits in 2 registers, it's left in 2 registers.
    3. If the value is larger than this, the caller reserves memory in its own stack and the function writes directly into the caller's stack.

    Both G++ & Clang do the same, this is tested on x86_64.