March 31, 2015 Re: Order of evaluation of a += a++; | ||||
---|---|---|---|---|
| ||||
Posted in reply to deadalnix | On 3/30/15 11:34 PM, deadalnix wrote: > On Tuesday, 31 March 2015 at 06:20:22 UTC, Andrei Alexandrescu wrote: >> On 3/30/15 8:49 PM, deadalnix wrote: >>> On Tuesday, 31 March 2015 at 01:01:24 UTC, Andrei Alexandrescu wrote: >>>> On 3/30/15 5:49 PM, deadalnix wrote: >>>>> Why are you doing the replacement top/down rather than bottom up ? >>>> >>>> What would be the alternative? -- Andrei >>> >>> Doing the replacement bottom up : >>> >>> a = a++; >>> >>> a += { auto olda = a; a = a + 1; return olda; }(); >>> >>> a = cast(typeof(a)) (a + { auto olda = a; a = a + 1; return olda; }()); >> >> You need another lowering here because you evaluate a twice. Consider: >> >> import std.stdio; >> int a; >> ref int fun() { writeln("meh"); return a; } >> void main() { >> fun() = i++; >> } >> > > Yeah, I had an int in mind. Make it > > { > aPtr = &a; > *aPtr = cast(typeof(a)) (*aPtr + { auto olda = *aPtr; *aPtr = a + > 1; return olda; }()); > return *aPtr; > }() So you propose the following lowering for e1 += e2: e1 += e2 -\> { auto __p = &(e1); *__p = cast(typeof(e1)) (*__p + e2); }() This looks contrived and it's no surprise is inconsistent with opOpAssign as you yourself noted. I prefer the lowering that identifies += to a function calls with two parameters: e1 += e2 -\> (ref a, b) { a = (cast(typeof(a)) (a + b); }(e1, e2) >>> Other code transformation do not require a function call to take place, >>> so why would this require one (which force eager evaluation of >>> parameters) ? >> >> Everything needs to be evaluated (and only once). >> >>> That is also inconsistent with LTR evaluation. >> >> I don't see how. >> > > a appear on the left of a++. a should be evaluated before a++. You > propose that it isn't. I see, thanks. Guess we should change the spec no matter what. My money is on the lowering I mentioned. Andrei |
March 31, 2015 Re: Order of evaluation of a += a++; | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Tuesday, 31 March 2015 at 06:50:16 UTC, Andrei Alexandrescu wrote:
> On 3/30/15 11:34 PM, deadalnix wrote:
>> On Tuesday, 31 March 2015 at 06:20:22 UTC, Andrei Alexandrescu wrote:
>>> On 3/30/15 8:49 PM, deadalnix wrote:
>>>> On Tuesday, 31 March 2015 at 01:01:24 UTC, Andrei Alexandrescu wrote:
>>>>> On 3/30/15 5:49 PM, deadalnix wrote:
>>>>>> Why are you doing the replacement top/down rather than bottom up ?
>>>>>
>>>>> What would be the alternative? -- Andrei
>>>>
>>>> Doing the replacement bottom up :
>>>>
>>>> a = a++;
>>>>
>>>> a += { auto olda = a; a = a + 1; return olda; }();
>>>>
>>>> a = cast(typeof(a)) (a + { auto olda = a; a = a + 1; return olda; }());
>>>
>>> You need another lowering here because you evaluate a twice. Consider:
>>>
>>> import std.stdio;
>>> int a;
>>> ref int fun() { writeln("meh"); return a; }
>>> void main() {
>>> fun() = i++;
>>> }
>>>
>>
>> Yeah, I had an int in mind. Make it
>>
>> {
>> aPtr = &a;
>> *aPtr = cast(typeof(a)) (*aPtr + { auto olda = *aPtr; *aPtr = a +
>> 1; return olda; }());
>> return *aPtr;
>> }()
>
> So you propose the following lowering for e1 += e2:
>
> e1 += e2
>
> -\>
>
> {
> auto __p = &(e1);
> *__p = cast(typeof(e1)) (*__p + e2);
> }()
>
> This looks contrived and it's no surprise is inconsistent with opOpAssign as you yourself noted. I prefer the lowering that identifies += to a function calls with two parameters:
>
> e1 += e2
>
> -\>
>
> (ref a, b) { a = (cast(typeof(a)) (a + b); }(e1, e2)
>
>>>> Other code transformation do not require a function call to take place,
>>>> so why would this require one (which force eager evaluation of
>>>> parameters) ?
>>>
>>> Everything needs to be evaluated (and only once).
>>>
>>>> That is also inconsistent with LTR evaluation.
>>>
>>> I don't see how.
>>>
>>
>> a appear on the left of a++. a should be evaluated before a++. You
>> propose that it isn't.
>
> I see, thanks.
>
> Guess we should change the spec no matter what. My money is on the lowering I mentioned.
>
>
> Andrei
I might be a bit confused here, but from what you're saying:
b += a++;
and
b += ++a;
Are doing the same thing in DMD?
|
March 31, 2015 Re: Order of evaluation of a += a++; | ||||
---|---|---|---|---|
| ||||
Posted in reply to Orvid King | On 3/31/15 12:18 AM, Orvid King wrote:
>
> I might be a bit confused here, but from what you're saying:
> b += a++;
> and
> b += ++a;
>
> Are doing the same thing in DMD?
No. Lowering of e1 += e2++ is:
e1 += e2++
-\>
(ref a, b) { a = (cast(typeof(a)) (a + b); }(
e1,
(ref a) { auto x = a; ++a; return x; }(e2)
)
whereas lowering of e1 += ++e2 is:
e1 += ++e2
-\>
(ref a, b) { a = (cast(typeof(a)) (a + b); }(
e1,
(ref a) { ++a; return a; }(e2)
)
Andrei
|
April 05, 2015 Re: Order of evaluation of a += a++; | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrei Alexandrescu | On Tuesday, 31 March 2015 at 08:17:31 UTC, Andrei Alexandrescu wrote:
> On 3/31/15 12:18 AM, Orvid King wrote:
>>
>> I might be a bit confused here, but from what you're saying:
>> b += a++;
>> and
>> b += ++a;
>>
>> Are doing the same thing in DMD?
>
> No. Lowering of e1 += e2++ is:
>
> e1 += e2++
>
> -\>
>
> (ref a, b) { a = (cast(typeof(a)) (a + b); }(
> e1,
> (ref a) { auto x = a; ++a; return x; }(e2)
> )
>
> whereas lowering of e1 += ++e2 is:
>
> e1 += ++e2
>
> -\>
>
> (ref a, b) { a = (cast(typeof(a)) (a + b); }(
> e1,
> (ref a) { ++a; return a; }(e2)
> )
>
>
> Andrei
Fixed in SDC.
|
April 05, 2015 Re: Order of evaluation of a += a++; | ||||
---|---|---|---|---|
| ||||
Posted in reply to deadalnix | On 4/4/15 7:54 PM, deadalnix wrote:
> On Tuesday, 31 March 2015 at 08:17:31 UTC, Andrei Alexandrescu wrote:
>> On 3/31/15 12:18 AM, Orvid King wrote:
>>>
>>> I might be a bit confused here, but from what you're saying:
>>> b += a++;
>>> and
>>> b += ++a;
>>>
>>> Are doing the same thing in DMD?
>>
>> No. Lowering of e1 += e2++ is:
>>
>> e1 += e2++
>>
>> -\>
>>
>> (ref a, b) { a = (cast(typeof(a)) (a + b); }(
>> e1,
>> (ref a) { auto x = a; ++a; return x; }(e2)
>> )
>>
>> whereas lowering of e1 += ++e2 is:
>>
>> e1 += ++e2
>>
>> -\>
>>
>> (ref a, b) { a = (cast(typeof(a)) (a + b); }(
>> e1,
>> (ref a) { ++a; return a; }(e2)
>> )
>>
>>
>> Andrei
>
> Fixed in SDC.
Awesome, thanks! -- Andrei
|
Copyright © 1999-2021 by the D Language Foundation