Evaluation order of index expressions

Timon Gehr via Digitalmars-d digitalmars-d at puremagic.com
Mon May 25 14:25:55 PDT 2015


On 05/25/2015 10:30 PM, Daniel Murphy wrote:
> "Timon Gehr"  wrote in message news:mjvvq2$19hd$1 at digitalmars.com...
>
>> > As operator overloading is defined in terms of lowering to function
>> > calls, I think it's reasonable to decide the order of evaluation after
>> > the lowering. This will still be consistent across compilers and
>> > platforms.
>>
>> But almost entirely arbitrary.
>
> Yes.  I don't think this is particularly important,

Those small ugly corners of the language do add up, and they do cause 
real problems. For issues like this one, which are not considered 
important enough, I think it is fine to fix the spec and let the 
compiler catch up later (with a warning in the spec). I'm not saying 
this is urgent, just that it is obvious how it ought to be.

> as depending on evaluation order is highly discouraged.
> ...

Doesn't mean it won't happen. Having different evaluation order for 
expressions that look identical is just asking for really funny problems 
in generic code, of the sort that will summon more threads like this one.

>> > Preserving the original order would require added complexity
>> > that I don't think is warranted.
>>
>> The compiler would just need to introduce some temporary variables for
>> the two lowerings. Why wouldn't this be warranted to make overloaded
>> operators consistent with built-in ones? If anything, I think it is
>> desirable to have opBinary(B) on type A and opBinaryRight(A) on type B
>> interchangeable.
>>
>> What complexity are you worried about?
>
> Introducing temporary variables is added complexity.  It affects all
> sorts of other parts of the compiler.

This ought to be a matter of changing a few lines in one place. Took me 
a couple of minutes to implement for opBinaryRight:

-    r=New!CallExp(opoverloadR,[e1]);
-    r.loc=loc;
+    auto tmpe=New!TmpVarExp(e1);
+    tmpe.loc=loc;
+    tmpe.semantic(sc);
+    version(assert) assert(!!tmpe.sym);
+    auto c=New!CallExp(opoverloadR,[tmpe.sym]);
+    r=New!(BinaryExp!(Tok!","))(tmpe,c);
+    r.loc=c.loc=loc;

What makes this different for DMD?



More information about the Digitalmars-d mailing list