rvalues -> ref (yup... again!)

Atila Neves atila.neves at gmail.com
Fri Mar 30 09:06:50 UTC 2018


On Tuesday, 27 March 2018 at 18:14:18 UTC, Manu wrote:
> On 27 March 2018 at 00:14, Atila Neves via Digitalmars-d 
> <digitalmars-d at puremagic.com> wrote:
>> On Monday, 26 March 2018 at 19:24:13 UTC, Manu wrote:
>>>
>>> On 26 March 2018 at 07:40, Atila Neves via Digitalmars-d 
>>> <digitalmars-d at puremagic.com> wrote:
>>>>
>>>> On Friday, 23 March 2018 at 22:01:44 UTC, Manu wrote:
>>>>>

>> That's _if_ T is big and _if_ it even gets copied,
>
> You've just described the exact anatomy of a ref function!
> You wouldn't write a function to receive T by ref UNLESS T was 
> both
> big, and the function probably won't inline (therefore 
> definitely
> copy), and that condition will be triggered by any of the list 
> of
> reasons I've said a bunch of times (extern, dll, lib, virtual, 
> etc).
> People don't just love writing ref (well, some people might), 
> but they
> use it deliberately, typically in user-facing boundary API's 
> for these
> exact reasons.

I know. I was arguing that those cases are uncommon and the API 
pain is therefore not too big of an issue. I'm pretty sure that 
you feel it more because of what you write in D.

> Right. I'm talking about deliberate use of ref... Or *existing*
> (deliberate) use of ref, as is the case in almost all my my 
> cases. The
> code already exists.

Right, and I was assuming (perhaps incorrectly) that this 
existing code was C++, hence me being on board with binding 
rvalues to const ref there.

> Only if you ARE moving, and not copying. D must deep copy too 
> if you
> actually copy.
> Your example assumes C++ doesn't have a move constructor. D has
> implicit move semantics, so you can only make an equivalent 
> comparison
> where C++ also defines the move constructor so the move case 
> doesn't
> pollute the ref comparison.

I wasn't assuming the lack of a move constructor. What I was 
saying is that passing by value in C++ will usually mean a copy, 
whereas in D it usually means a move.

> Also, irrespective of whether move semantics are performed 
> (eliding
> potential deep copying, as in your example), the binary memcpy 
> still
> has to be performed when handling values by-val, unless RVO 
> (we're not
> talking about return values), or inlining is able to eliminate 
> it.

Good point about memcpy.

>>> In C++'s case, it's not that references were deficient at 
>>> being references that C++ needed rval-references, it's that 
>>> references were deficient at being move-able.
>>
>>
>> There were deficient at being moveable because temporaries can 
>> bind to const T&.
>
> ... what? That's just not true at all.
> If temporaries couldn't bind to C++ ref, then you *definitely*
> wouldn't be able to move it, because you can guarantee that 
> someone
> else owns the reference.

Precisely. That's how D works.


> rvalue references were introduced in C++ to capture the calls 
> with
> rvalues into a separate function call, exactly the same way as 
> the
> by-value overload will catch the rvalues in D (and perform an 
> implicit
> move).

Yes.

> It was impossible for C++ to implement D's implicit move 
> semantics
> when receiving by-value for reasons that have nothing to do with
> references; C++ allows interior pointers which breaks implicit 
> moving,
> C++ can overload default constructor which also breaks implicit 
> moving
> (no implicit way to reset the state of the prior owner).

I hadn't thought about the implications of interior pointers. 
Very good point.

> References have no interaction with move semantics.

Even given interior pointers, I disagree.

> But again, we're not talking about move semantics here, we're 
> just talking about references ;)

See comment above ;)

>> I'd love to know what that would look like.
>
> That's exactly what I've been saying. For like, 9 years..
> It looks like this:
> https://github.com/TurkeyMan/DIPs/blob/ref_args/DIPs/DIP1xxx-rval_to_ref.md
>  (contribution appreciated)

I was unaware of this (or I forgot). After reading it I'm not 
sure of what corner cases might arise, but if I'm getting it 
right I think it could work.

> And as far as I
> can tell, it basically only affects me, because I do so much 
> work
> against established C++ code! >_<

That's entirely possible. I can use my fingers to count the 
number of times I've written `extern(C++)`.

Atila




More information about the Digitalmars-d mailing list