Slice expressions - exact evaluation order, dollar

Iain Buclaw via Digitalmars-d digitalmars-d at puremagic.com
Tue Jul 12 14:56:50 PDT 2016


On 27 June 2016 at 04:38, Timon Gehr via Digitalmars-d
<digitalmars-d at puremagic.com> wrote:
> On 26.06.2016 20:08, Iain Buclaw via Digitalmars-d wrote:
>>
>> On 26 June 2016 at 14:33, Timon Gehr via Digitalmars-d
>> <digitalmars-d at puremagic.com> wrote:
>>>
>>> On 26.06.2016 10:08, Iain Buclaw via Digitalmars-d wrote:
>>>>
>>>>
>>>> Old codegen:
>>>>
>>>> _base = *(getBase());
>>>> _lwr = getLowerBound(_base.length);
>>>> _upr = getUpperBound(_base.length);
>>>> r = {.length=(_upr - _lwr), .ptr=_base.ptr + _lwr * 4};
>>>>
>>>> ---
>>>
>>>
>>>
>>> This seems to be what I'd expect. It's also what CTFE does.
>>> CTFE and run time behaviour should be identical. (So either one of them
>>> needs to be fixed.)
>>>
>>>
>>
>> Very likely CTFE.  Anyway, this isn't the only thing where CTFE and
>> Runtime do things differently.
>> ...
>
>
> All arbitrary differences should be eradicated.
>
>>>> Now when creating temporaries of references, the reference is stabilized
>>>> instead.
>>>>
>>>> New codegen:
>>>>
>>>> *(_ptr = getBase());
>>>> _lwr = getLowerBound(_ptr.length);
>>>> _upr = getUpperBound(_ptr.length);
>>>> r = {.length=(_upr - _lwr), .ptr=_ptr.ptr + _lwr * 4};
>>>> ---
>>>>
>>>> I suggest you fix LDC if it doesn't already do this. :-)
>>>
>>>
>>>
>>>
>>> I'm not convinced this is a good idea. It makes
>>> (()=>base)()[lwr()..upr()]
>>> behave differently from base[lwr()..upr()].
>>
>>
>> No, sorry, I'm afraid you are wrong there. They should both behave
>> exactly the same.
>> ...
>
>
> I don't see how that is possible, unless I misunderstood your previous
> explanation. 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.
>
>
>> I may need to step aside and explain what changed in GDC, as it had
>> nothing to do with this LDC bug.
>>
>> ==> Step
>>
>> What made this subtle change was in relation to fixing bug 42 and 228
>> in GDC, which involved turning on TREE_ADDRESSABLE(type) bit in our
>> codegen trees, which in turn makes NRVO work consistently regardless
>> of optimization flags used - no more optimizer being confused by us
>> "faking it".
>>
>> How is the above jargon related? Well, one of the problems faced was
>> that it must be ensured that lvalues continue being lvalues when
>> considering creating a temporary in the codegen pass.  Lvalue
>> references must have the reference stabilized, not the value that is
>> being dereferenced.  This also came with an added assurance that GDC
>> will now *never* create a temporary of a decl with a cpctor or dtor,
>> else it'll die with an internal compiler error trying. :-)
>> ...
>
>
> 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.

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.

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


More information about the Digitalmars-d mailing list