On Monday, 26 March 2018 at 19:24:13 UTC, Manu wrote:
On 26 March 2018 at 07:40, Atila Neves via Digitalmars-d
<[email protected]> wrote:
On Friday, 23 March 2018 at 22:01:44 UTC, Manu wrote:
Forked from the x^^y thread...
<snip>
C++ T&& (forwarding reference) -> D auto ref T
C++ T&& (Rvalue reference) -> D T
C++ const T& -> D T
Yeah, no... T may be big. Copying a large thing sucks. Memory
copying
is the slowest thing computers can do.
That's _if_ T is big and _if_ it even gets copied, the
combination of which I think happens very rarely. When that
happens I think that the temporary isn't a big deal. This code:
struct Foo { int[1024] data; }
int byValue(Foo f) { return f.data[42]; }
Generates this assembly (ldc2 -O3, clang does the same for C++):
0000000000000000 <_D3foo7byValueFSQo3FooZi>:
0: 8b 84 24 b0 00 00 00 mov eax,DWORD PTR [rsp+0xb0]
7: c3 ret
And I wrote a type for which a move and a copy are the same on
purpose: in "real life" it's more likely that the memory will be
dynamically allocated, probably held in a slice, and moved
instead.
Are there cases in which there will be an expensive copy? Yes,
then pass by ref/pointer. But measure first, and prefer to pass
by value by default.
It's different in C++ - stick a std::vector or std::string in
your struct and passing by value (usually) copies the dynamically
allocated memory. In D it moves.
As an API author, exactly as in C++, you will make a judgement
on a
case-by-case basis on this matter. It may be by-value, it may
be by
const-ref. It depends on a bunch of things, and they are points
for
consideration by the API author, not the user.
You can still do that in D. There well may be a reason to pass by
const ref. I'm just saying that there aren't that many, and in
that in those rare cases a temporary is fine. Especially if the
alternative are rvalue references.
Atila