Jump to page: 1 2
Thread overview
Evaluation order of "+="
Jul 11, 2016
Johan Engelen
Jul 11, 2016
Danika
Jul 12, 2016
deadalnix
Jul 12, 2016
Patrick Schluter
Jul 12, 2016
Patrick Schluter
Jul 12, 2016
Johan Engelen
Jul 12, 2016
deadalnix
Jul 12, 2016
Johan Engelen
Jul 12, 2016
Johan Engelen
Jul 13, 2016
Timon Gehr
Jul 13, 2016
Iain Buclaw
Jul 12, 2016
kink
Jul 12, 2016
deadalnix
Jul 12, 2016
Johan Engelen
Jul 12, 2016
Iain Buclaw
July 11, 2016
LDC recently changed the evaluation order of "+=" (I think unintentionally, some other eval order problems were fixed). Now, it is different from DMD.
I am going to argue that I think DMD's order is more useful in the context of fibers, and would like your opinion.

Consider this code:
```
int sum;

int return1_add9tosum() {
    sum += 9;
    return 1;
}

void main() {
    sum = 0;
    sum += return1_add9tosum();

    import std.stdio;
    writeln(sum);
}
```
DMD 2.071 prints "10".
LDC master prints "1". (LDC 1.0.0 prints "10")

I find the spec [1] to be unclear on this point, so which one is correct?

The bug was caught by code involving fibers. Instead of `return1_add9tosum`, a function `return1_yieldsFiber` is called, and multiple fibers write to `sum`. In that case, upon completing the "+=", an older version of `sum` is used to calculate the result. I think that it is best to do what DMD does, such that fibers can do "+=" without worrying about yields on the rhs.

[1] https://dlang.org/spec/expression.html
July 11, 2016
On Monday, 11 July 2016 at 23:04:00 UTC, Johan Engelen wrote:
> LDC recently changed the evaluation order of "+=" (I think unintentionally, some other eval order problems were fixed). Now, it is different from DMD.
> I am going to argue that I think DMD's order is more useful in the context of fibers, and would like your opinion.

I really think it is a bug, in C it prints 10. And following the flow, you changed the sum to 9 and after that added 1, so It would be 10.6
July 12, 2016
On Monday, 11 July 2016 at 23:31:40 UTC, Danika wrote:
> On Monday, 11 July 2016 at 23:04:00 UTC, Johan Engelen wrote:
>> LDC recently changed the evaluation order of "+=" (I think unintentionally, some other eval order problems were fixed). Now, it is different from DMD.
>> I am going to argue that I think DMD's order is more useful in the context of fibers, and would like your opinion.
>
> I really think it is a bug, in C it prints 10. And following the flow, you changed the sum to 9 and after that added 1, so It would be 10.6

In C, it is UB.

July 12, 2016
On Monday, 11 July 2016 at 23:04:00 UTC, Johan Engelen wrote:
> LDC recently changed the evaluation order of "+=" (I think unintentionally, some other eval order problems were fixed). Now, it is different from DMD.
> I am going to argue that I think DMD's order is more useful in the context of fibers, and would like your opinion.
>
> Consider this code:
> ```
> int sum;
>
> int return1_add9tosum() {
>     sum += 9;
>     return 1;
> }
>
> void main() {
>     sum = 0;
>     sum += return1_add9tosum();
>
>     import std.stdio;
>     writeln(sum);
> }
> ```
> DMD 2.071 prints "10".
> LDC master prints "1". (LDC 1.0.0 prints "10")
>
> I find the spec [1] to be unclear on this point, so which one is correct?
>
> The bug was caught by code involving fibers. Instead of `return1_add9tosum`, a function `return1_yieldsFiber` is called, and multiple fibers write to `sum`. In that case, upon completing the "+=", an older version of `sum` is used to calculate the result. I think that it is best to do what DMD does, such that fibers can do "+=" without worrying about yields on the rhs.
>
> [1] https://dlang.org/spec/expression.html

There was a very lenghty discussion about this in the past. DMD is correct on that one. The semantic is such as :

int plusEqual(ref int a, int b) {
  a = a + b;
  return a;
}

July 12, 2016
On Tuesday, 12 July 2016 at 00:16:58 UTC, deadalnix wrote:
> On Monday, 11 July 2016 at 23:31:40 UTC, Danika wrote:
>> On Monday, 11 July 2016 at 23:04:00 UTC, Johan Engelen wrote:
>>> LDC recently changed the evaluation order of "+=" (I think unintentionally, some other eval order problems were fixed). Now, it is different from DMD.
>>> I am going to argue that I think DMD's order is more useful in the context of fibers, and would like your opinion.
>>
>> I really think it is a bug, in C it prints 10. And following the flow, you changed the sum to 9 and after that added 1, so It would be 10.6
>
> In C, it is UB.

A function call is a sequence point in C, so it is not UB. What happens here in LDC is probably that the call is inlined and therefore losing the sequence point. That is one of the dangers of aggressive inlining. The behaviour described by op would be definitly a bug in C. For D I don't know as I don't know if the sequence point rules are as strictly defined as in C.
July 12, 2016
On Tuesday, 12 July 2016 at 05:46:58 UTC, Patrick Schluter wrote:
> On Tuesday, 12 July 2016 at 00:16:58 UTC, deadalnix wrote:
>> On Monday, 11 July 2016 at 23:31:40 UTC, Danika wrote:
>>> On Monday, 11 July 2016 at 23:04:00 UTC, Johan Engelen wrote:
>>>> LDC recently changed the evaluation order of "+=" (I think unintentionally, some other eval order problems were fixed). Now, it is different from DMD.
>>>> I am going to argue that I think DMD's order is more useful in the context of fibers, and would like your opinion.
>>>
>>> I really think it is a bug, in C it prints 10. And following the flow, you changed the sum to 9 and after that added 1, so It would be 10.6
>>
>> In C, it is UB.
>
> A function call is a sequence point in C, so it is not UB.

UB happens when a variable is changed more than once between sequence points, which is not the case here.

> What happens here in LDC is probably that the call is inlined and therefore losing the sequence point. That is one of the dangers of aggressive inlining. The behaviour described by op would be definitly a bug in C. For D I don't know as I don't know if the sequence point rules are as strictly defined as in C.


July 12, 2016
On Tuesday, 12 July 2016 at 05:46:58 UTC, Patrick Schluter wrote:
> 
> What happens here in LDC is probably that the call is inlined and therefore losing the sequence point. That is one of the dangers of aggressive inlining.

Going off-topic but briefly: all inlining in LDC happens by LLVM. With the possibility of LLVM bugs, bugs by inlining are very rare I'd think.
(in this case, it happens for debug builds (so no inlining) too.)
July 12, 2016
On Tuesday, 12 July 2016 at 02:27:04 UTC, deadalnix wrote:
>
> There was a very lenghty discussion about this in the past. DMD is correct on that one. The semantic is such as :
>
> int plusEqual(ref int a, int b) {
>   a = a + b;
>   return a;
> }

Thanks.
Could this be added to the spec please?

July 12, 2016
On Tuesday, 12 July 2016 at 07:57:37 UTC, Johan Engelen wrote:
> On Tuesday, 12 July 2016 at 02:27:04 UTC, deadalnix wrote:
>>
>> There was a very lenghty discussion about this in the past. DMD is correct on that one. The semantic is such as :
>>
>> int plusEqual(ref int a, int b) {
>>   a = a + b;
>>   return a;
>> }
>
> Thanks.
> Could this be added to the spec please?

https://github.com/dlang/dlang.org/pull/1429
July 12, 2016
On Tuesday, 12 July 2016 at 02:27:04 UTC, deadalnix wrote:
> There was a very lenghty discussion about this in the past. DMD is correct on that one.

Great, so after that very lengthy discussion, why did nobody add a frigging test?! Argh.
« First   ‹ Prev
1 2