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.