Slice expressions - exact evaluation order, dollar

Iain Buclaw via Digitalmars-d digitalmars-d at puremagic.com
Sun Jun 26 11:08:47 PDT 2016


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.

>> 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 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. :-)

<== Step

(() => base)[lwr()..up()] will make a temporary of (() => base), but
guarantees that references are stabilized first.

base[lwr()..upr()] will create no temporary if base has no side
effects.  And so if lwr() modifies base, then upr() will get the
updated copy.


More information about the Digitalmars-d mailing list