On Sat, Jul 30, 2022 at 8:08 AM Tom Lane <t...@sss.pgh.pa.us> wrote: > Robert Haas <robertmh...@gmail.com> writes: > > I was taught that when programming in C one should avoid returning a > > struct type, as BufTagGetRelFileLocator does. > > FWIW, I think that was invalid pre-ANSI-C, and maybe even in C89. > C99 and later requires it. But it is pass-by-value and you have > to think twice about whether you want the struct to be copied.
C89 had that. As for what it actually does in a non-inlined function: on all modern Unix-y systems, 128 bit first arguments and return values are transferred in register pairs[1]. So if you define a struct that holds uint32_t, uint32_t, uint64_t and compile a function that takes one and returns it, you see the struct being transferred directly from input registers to output registers: 0x0000000000000000 <+0>: mov %rdi,%rax 0x0000000000000003 <+3>: mov %rsi,%rdx 0x0000000000000006 <+6>: ret Similar on ARM64. There it's an empty function, so it must be using the same register in and out[2]. The MSVC calling convention is different and doesn't seem to be able to pass it through registers, so it schleps it out to memory at a return address[3]. But that's pretty similar to the proposed alternative anyway, so surely no worse. *shrug* And of course those "constructor"-like functions are inlined anyway. [1] https://en.wikipedia.org/wiki/X86_calling_conventions#System_V_AMD64_ABI [2] https://gcc.godbolt.org/z/qfPzhW7YM [3] https://gcc.godbolt.org/z/WqvYz6xjs