July 13, 2016
On Monday, 27 June 2016 at 02:38:22 UTC, Timon Gehr wrote:
> As far as I understand, for the first expression, code gen will generate a reference to a temporary copy of base, and for the second expression, it will generate a reference to base directly. If lwr() or upr() then update the ptr and/or the length of base, those changes will be seen for the second slice expression, but not for the first.

Exactly. That's what I initially asked in

> Should the returned slice be based on the slicee's buffer before or after evaluating the bounds expressions?

So Timon prefers the pre-buffer (apparently what DMD does), GDC does the post-buffer, and LDC buggily something inbetween (for $, we treat base.length as lvalue, but we load base.ptr before evaluating the bounds, hence treating base as rvalue there).

Can we agree on something, add corresponding tests and make sure CTFE works exactly the same? %)

> The point is that the slice expression itself does or does not see the updates based on whether I wrap base in a lambda or not.

I don't really see a necessity for the lambda to return the same kind (lvalue/rvalue) of value as the expression directly.
July 13, 2016
On Wednesday, 13 July 2016 at 21:06:28 UTC, kinke wrote:
> On Monday, 27 June 2016 at 02:38:22 UTC, Timon Gehr wrote:
>> The point is that the slice expression itself does or does not see the updates based on whether I wrap base in a lambda or not.
>
> I don't really see a necessity for the lambda to return the same kind (lvalue/rvalue) of value as the expression directly.

Oh, that's actually https://issues.dlang.org/show_bug.cgi?id=16271.

So lambda wrapping isn't the issue here. It's just that both ways of dealing with the base are possible and arguably plausible. Is the current DMD way (base treated as rvalue) the one to be followed or has just nobody given this a deeper thought yet?
July 14, 2016
On Friday, 17 June 2016 at 19:59:09 UTC, kinke wrote:
> // LDC issue #1433
> void main()
> {
>     auto r = getBase()[getLowerBound($) .. getUpperBound($)];
>     assert(r == [ 2, 3 ]);
> }
>
> Firstly, it fails with DMD 2.071 because $ in the upper bound expression is 0, i.e., it doesn't reflect the updated length (1) after evaluating the lower bound expression. LDC does.

The docs aren't fully detailed, but this is explicit behavior in the DMD front end that is the same no matter what type getBase() returns:

"Note that opDollar!i is only evaluated once for each i where $ occurs in the corresponding position in the indexing operation." - https://dlang.org/spec/operatoroverloading.html

"PostfixExpression is evaluated. if PostfixExpression is an expression of type static array or dynamic array, the special variable $ is declared and set to be the length of the array. " - https://dlang.org/spec/expression.html
July 19, 2016
On 12.07.2016 23:56, Iain Buclaw via Digitalmars-d wrote:
>> >
>> >What is the justification why the base should be evaluated as an lvalue?
>> >
> Because changes made to a temporary get lost as they never bind back
> to the original reference.
> ...

Which I'd expect. It is just like:

int x = 0;
assert(3 == ++x + ++x);

If the first '++x' was evaluated by reference, this would be 4, not 3.


> Regardless, creating a temporary of a struct with a cpctor violates
> the semantics of the type - it's the job of the frontend to generate
> all the code for lifetime management for us.
> ...

Yes, but the front end can also be wrong. What is unclear here is if/why the front end should evaluate the array base by reference.


> (Sorry for the belated response, I have been distracted).

(Me too.)
1 2
Next ›   Last »