__rvalue and Move Semantics first draft - aliasing problem/danger

kinke noone at nowhere.com
Mon Nov 11 11:31:43 UTC 2024


On Sunday, 10 November 2024 at 17:36:25 UTC, Timon Gehr wrote:
> On 11/9/24 23:44, Walter Bright wrote:
>> I'm not sure it's a problem or a danger.
>> 
>> Timon mentioned the related problem with:
>> 
>> ```
>> callee(__rvalue s, __rvalue s);
>> ```
>> 
>> where s would be destroyed twice. This isn't always detectable:
>> ```
>> S* ps = ...;
>> callee(__rvalue *s, __rvalue(*s));
>> ```
>> But can be rendered benign with the blit of S.init after the 
>> destructor call.

But that's at least already invalid/undefined in your proposal. 
I've used `callee(lval, __rvalue(lval))` to show that the 
aliasing problem can occur in valid code too - `lval` isn't 
accessed lexically after __rvalue'ing it. __rvalue'ing a global 
variable and checking that the global isn't accessed in the 
callee is even harder.

> I think the main potential trouble is that there is usually an 
> assumption that there is no aliasing between rvalue arguments.

It's not just an assumption, it's an implicit guarantee - a 
by-value parameter is analogous to a local in high-level terms, 
so of course with its own distinct private memory. Well, until 
now. :)

> For example, if a compiler backend assumes no aliasing, 
> undefined behavior might be introduced if one of the arguments 
> is modified and then the other is read.

This isn't just a problem with compiler optimizations, but in 
general:

```D
void callee(const ref S x, S y) {
     y.bla = x.bla - 1;
     assert(y.bla != x.bla, "have changed ref via value alias!");
}
```


More information about the dip.development mailing list