Taking arguments by value or by reference

Max Haughton maxhaton at gmail.com
Mon Oct 5 00:47:57 UTC 2020

On Sunday, 4 October 2020 at 14:26:43 UTC, Anonymouse wrote:
> On Saturday, 3 October 2020 at 23:47:32 UTC, Max Haughton wrote:
>> The guiding principle to your function parameters should be 
>> correctness - if I am passing a big struct around, if I want 
>> to take ownership of it I probably want to take it by value 
>> but if I want to modify it I should take it by reference (or 
>> by pointer but don't overcomplicate, notice in the previous 
>> example they lower to the same thing). If I just want to look 
>> at it, it should be taken by const ref if possible (D const 
>> isn't the same as C++ const, this may catch you out).
>> Const-correctness is a rule to live by especially with an big 
>> unwieldy struct.
>> I would avoid the new in for now, but I would go with const 
>> ref from what you've described so far.
> I mostly really only want a read-only view of the struct, and 
> whether a copy was done or not is academic. However, profiling 
> showed (what I interpret as) a lot of copying being done in 
> release builds specifically.
> https://i.imgur.com/JJzh4Zc.jpg
> Naturally a situation where I need ref I'd use ref, and in the 
> rare cases where it actually helps to have a mutable copy 
> directly I take it mutable. But if I understand what you're 
> saying, and ignoring --preview=in, you'd recommend I use const 
> ref where I would otherwise use const?
> Is there some criteria I can go by when making this decision, 
> or does it always reduce to looking at the disassembly?

This is skill you only really hone with experience, but it's not 
too bad once you're used to it.

For a big struct, I would just stick to expressing what you want 
it to *do* rather than how you want it to perform. If you want to 
take ownership you basically have to take by value, but if you 
(as you said) want a read only view definitely const ref. If I 
was reading your code, ref immediately tells me not to think 
about ownership and const ref immediately tells me you just want 
to look at the goods.

One thing I haven't mentioned so far is that not all types have 
non-trivial semantics when it comes to passing them around by 
value, so if you are writing generic code it is often best to 
avoid these.

More information about the Digitalmars-d-learn mailing list