pass a struct by value/ref and size of the struct

ZombineDev via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Apr 2 02:28:58 PDT 2016


On Wednesday, 23 March 2016 at 19:39:49 UTC, kinke wrote:
> On Tuesday, 22 March 2016 at 07:35:49 UTC, ZombineDev wrote:
>> If the object is larger than the size of a register on the 
>> target machine, it is implicitly passed by ref
>
> That's incorrect. As Johan pointed out, this is somewhat true 
> for the Win64 ABI (but it firstly copies the argument before 
> passing a pointer to it!), but it's not for the 32-bit x86 and 
> x86_64 System V (used on all non-Windows platforms) ABIs. 
> System V is especially elaborate and may pass structs up to 
> twice the size of a register in 2 registers. Bigger structs 
> passed by value are blitted into the function arguments stack 
> in memory. They are then accessed by the callee via a stack 
> offset, that's correct, but I wouldn't call that 
> implicit-by-ref-passing, as copying does take place, unless the 
> optimizer decides it's unnecessary.
>
> So passing structs > 64-bit by value on Win64 never pays off 
> (there's always an indirection); using `const ref(T)` where 
> possible makes sure you at least elide the copy. But then 
> again, you'll very soon find out that it's not really an option 
> as rvalues cannot be passed byref in D, something a lot of 
> people [including myself if not already obvious :)] hate about 
> D.

Thank you and Johan for the detailed explanation. You're efforts 
on improving LDC are much appreciated.
My intentions were to say that taking structs by value shouldn't 
be as expensive as in C++, because of the way D handles copy 
construction, especially if there is no user-defined postblit 
(which is quite common), and also because separate compilation is 
used more rarely.
But probably I shouldn't have said that about the size of 
registers as it depends very much on the ABI and it's not true in 
general (as you pointed out).

BTW, how does LDC handle the `auto ref` and `in` parameter 
attributes for templated functions (that obviously have their 
source code available)? Can they be used to prevent indirection 
when the structure can be passed in registers and to prevent 
copying when passing by registers is not possible?


More information about the Digitalmars-d-learn mailing list