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

Reply via email to