Jump to page: 1 2
Thread overview
postincrement behaviour (differences between dmd and gdc)
Apr 20, 2011
Iain Buclaw
Apr 20, 2011
spir
Apr 20, 2011
Jonathan M Davis
Apr 20, 2011
Dmitry Olshansky
Apr 20, 2011
Mafi
Apr 20, 2011
Dmitry Olshansky
Apr 20, 2011
Mafi
Apr 20, 2011
Kagamin
Apr 20, 2011
Kagamin
Apr 20, 2011
bearophile
Apr 20, 2011
Daniel Gibson
Apr 20, 2011
KennyTM~
Apr 21, 2011
maarten van damme
April 20, 2011
This was partially discussed before some time ago - http://www.digitalmars.com/d/archives/digitalmars/D/postincrement_behaviour_differences_between_dmd_and_gdc_47334.html


The following statement has different behaviours in dmd and gdc.

int x;
x = x++;


Where the backend for DMD interprets it as:

  tmp = x;
  x++;
  x = tmp;

And the backend for GDC interprets it as:

  x = x;
  x++;


Skipping all undefined behaviour/which one is correct talk, an alternative suggestion would be to treat such nonsensical code as an error - like "Cannot modify the value of a variable twice in the same expression." - as this kind of thing I would expect to be almost always a bug.


Regards
April 20, 2011
On 04/20/2011 11:33 AM, Iain Buclaw wrote:
> This was partially discussed before some time ago -
> http://www.digitalmars.com/d/archives/digitalmars/D/postincrement_behaviour_differences_between_dmd_and_gdc_47334.html
>
>
> The following statement has different behaviours in dmd and gdc.
>
> int x;
> x = x++;
>
>
> Where the backend for DMD interprets it as:
>
>    tmp = x;
>    x++;
>    x = tmp;
>
> And the backend for GDC interprets it as:
>
>    x = x;
>    x++;
>
>
> Skipping all undefined behaviour/which one is correct talk, an alternative
> suggestion would be to treat such nonsensical code as an error - like "Cannot
> modify the value of a variable twice in the same expression." - as this kind
> of thing I would expect to be almost always a bug.

Very probable. Also, the dmd interpretation makes even less sense for me. At least, gdc performs what the probable intent is. But an error is certainly far better.

denis
-- 
_________________
vita es estrany
spir.wikidot.com

April 20, 2011
> This was partially discussed before some time ago - http://www.digitalmars.com/d/archives/digitalmars/D/postincrement_behaviour _differences_between_dmd_and_gdc_47334.html
> 
> 
> The following statement has different behaviours in dmd and gdc.
> 
> int x;
> x = x++;
> 
> 
> Where the backend for DMD interprets it as:
> 
>   tmp = x;
>   x++;
>   x = tmp;
> 
> And the backend for GDC interprets it as:
> 
>   x = x;
>   x++;
> 
> 
> Skipping all undefined behaviour/which one is correct talk, an alternative suggestion would be to treat such nonsensical code as an error - like "Cannot modify the value of a variable twice in the same expression." - as this kind of thing I would expect to be almost always a bug.

Actually, I would have expected postincrement and preincrement to be identical in this case. It was my understanding that the entire expression to the right of the assignment operator was evaluated before the assignment was made, but I guess I could see how that could be open to interpretation with regards to the postincrement operator.

Regardless, I think that making this sort of case an error would make good sense.

- Jonathan M Davis
April 20, 2011
On 20.04.2011 13:53, Jonathan M Davis wrote:
>> This was partially discussed before some time ago -
>> http://www.digitalmars.com/d/archives/digitalmars/D/postincrement_behaviour
>> _differences_between_dmd_and_gdc_47334.html
>>
>>
>> The following statement has different behaviours in dmd and gdc.
>>
>> int x;
>> x = x++;
>>
>>
>> Where the backend for DMD interprets it as:
>>
>>    tmp = x;
>>    x++;
>>    x = tmp;
>>
>> And the backend for GDC interprets it as:
>>
>>    x = x;
>>    x++;
>>
>>
>> Skipping all undefined behaviour/which one is correct talk, an alternative
>> suggestion would be to treat such nonsensical code as an error - like
>> "Cannot modify the value of a variable twice in the same expression." - as
>> this kind of thing I would expect to be almost always a bug.
> Actually, I would have expected postincrement and preincrement to be identical
> in this case. It was my understanding that the entire expression to the right
> of the assignment operator was evaluated before the assignment was made, but I
> guess I could see how that could be open to interpretation with regards to the
> postincrement operator.
>
No, I think post-increment is done after the whole expression is evaluated, see the common C idiom:

*p++ = *q++;
it's always interpreted as:
*p = *q;
p++,q++; // or q++,p++;


> Regardless, I think that making this sort of case an error would make good
> sense.
>
Agreed, using variable as an L-value and post-incrementing it in the same expression is plain mistake.

> - Jonathan M Davis


-- 
Dmitry Olshansky

April 20, 2011
Iain Buclaw Wrote:

> And the backend for GDC interprets it as:
> 
>   x = x;
>   x++;

As I understand, you pass the expression to the backend as is, the backend interprets it in the C way, and you get surprising result on discrepancy between C and D semantics?
April 20, 2011
Iain Buclaw Wrote:

> suggestion would be to treat such nonsensical code as an error - like "Cannot modify the value of a variable twice in the same expression." - as this kind of thing I would expect to be almost always a bug.

What about this?

x=(*y)++;
April 20, 2011
Am 20.04.2011 12:01, schrieb Dmitry Olshansky:
> On 20.04.2011 13:53, Jonathan M Davis wrote:
>>> This was partially discussed before some time ago -
>>> http://www.digitalmars.com/d/archives/digitalmars/D/postincrement_behaviour
>>>
>>> _differences_between_dmd_and_gdc_47334.html
>>>
>>>
>>> The following statement has different behaviours in dmd and gdc.
>>>
>>> int x;
>>> x = x++;
>>>
>>>
>>> Where the backend for DMD interprets it as:
>>>
>>> tmp = x;
>>> x++;
>>> x = tmp;
>>>
>>> And the backend for GDC interprets it as:
>>>
>>> x = x;
>>> x++;
>>>
>>>
>>> Skipping all undefined behaviour/which one is correct talk, an
>>> alternative
>>> suggestion would be to treat such nonsensical code as an error - like
>>> "Cannot modify the value of a variable twice in the same expression."
>>> - as
>>> this kind of thing I would expect to be almost always a bug.
>> Actually, I would have expected postincrement and preincrement to be
>> identical
>> in this case. It was my understanding that the entire expression to
>> the right
>> of the assignment operator was evaluated before the assignment was
>> made, but I
>> guess I could see how that could be open to interpretation with
>> regards to the
>> postincrement operator.
>>
> No, I think post-increment is done after the whole expression is
> evaluated, see the common C idiom:
>
> *p++ = *q++;
> it's always interpreted as:
> *p = *q;
> p++,q++; // or q++,p++;
>

IMHO it should be interpreted as

typeof(p) tmp_p;
typeof(q) tmp_q;
*((tmp_p = p), ++p, tmp_p) = *((tmp_q = q), q++, tmp_q);

In this case the overall semantics are identical but your expandation looks like gdc's and mine like dmd's. Therefore I think dmd's is more correct although less useful.

Generally I think it should just be an error to assign twice in the same expression.

Mafi
April 20, 2011
Iain Buclaw:

> Skipping all undefined behaviour/which one is correct talk, an alternative suggestion would be to treat such nonsensical code as an error - like "Cannot modify the value of a variable twice in the same expression." - as this kind of thing I would expect to be almost always a bug.

Thank you for raising this topic again. In my opinion in a modern language, even a system language, this kind of undefined (and different across different compilers) is _not_ acceptable.
Another source of some undefined behaviours are function calls.

Two possible solutions for D:
- Turn such situations that lead to undefined behaviour into syntax errors;
- Do define and standardize such behaviours, even if this may cause tiny performance losses on some CPUs.

Bye,
bearophile
April 20, 2011
Am 20.04.2011 12:58, schrieb bearophile:
> Iain Buclaw:
>
>> Skipping all undefined behaviour/which one is correct talk, an alternative
>> suggestion would be to treat such nonsensical code as an error - like "Cannot
>> modify the value of a variable twice in the same expression." - as this kind
>> of thing I would expect to be almost always a bug.
>
> Thank you for raising this topic again. In my opinion in a modern language, even a system language, this kind of undefined (and different across different compilers) is _not_ acceptable.
> Another source of some undefined behaviours are function calls.
>

I think the DMD way is conformant with the D2 specification, see http://digitalmars.com/d/2.0/operatoroverloading.html
"e++ [is rewritten as] (auto t=e, ++e, t)", so x=x++; shouldn't change the value of x. (Yeah, this is for overloading, but the operator should behave the same for simple types).

Of course x = x++; still makes no sense and should probably cause a warning or an error.

> Two possible solutions for D:
> - Turn such situations that lead to undefined behaviour into syntax errors;
> - Do define and standardize such behaviours, even if this may cause tiny performance losses on some CPUs.
>
> Bye,
> bearophile

Cheers,
- Daniel
April 20, 2011
On 20.04.2011 14:16, Mafi wrote:
> Am 20.04.2011 12:01, schrieb Dmitry Olshansky:
>> On 20.04.2011 13:53, Jonathan M Davis wrote:
>>>> This was partially discussed before some time ago -
>>>> http://www.digitalmars.com/d/archives/digitalmars/D/postincrement_behaviour 
>>>>
>>>>
>>>> _differences_between_dmd_and_gdc_47334.html
>>>>
>>>>
>>>> The following statement has different behaviours in dmd and gdc.
>>>>
>>>> int x;
>>>> x = x++;
>>>>
>>>>
>>>> Where the backend for DMD interprets it as:
>>>>
>>>> tmp = x;
>>>> x++;
>>>> x = tmp;
>>>>
>>>> And the backend for GDC interprets it as:
>>>>
>>>> x = x;
>>>> x++;
>>>>
>>>>
>>>> Skipping all undefined behaviour/which one is correct talk, an
>>>> alternative
>>>> suggestion would be to treat such nonsensical code as an error - like
>>>> "Cannot modify the value of a variable twice in the same expression."
>>>> - as
>>>> this kind of thing I would expect to be almost always a bug.
>>> Actually, I would have expected postincrement and preincrement to be
>>> identical
>>> in this case. It was my understanding that the entire expression to
>>> the right
>>> of the assignment operator was evaluated before the assignment was
>>> made, but I
>>> guess I could see how that could be open to interpretation with
>>> regards to the
>>> postincrement operator.
>>>
>> No, I think post-increment is done after the whole expression is
>> evaluated, see the common C idiom:
>>
>> *p++ = *q++;
>> it's always interpreted as:
>> *p = *q;
>> p++,q++; // or q++,p++;
>>
>
> IMHO it should be interpreted as
>
> typeof(p) tmp_p;
> typeof(q) tmp_q;
> *((tmp_p = p), ++p, tmp_p) = *((tmp_q = q), q++, tmp_q);

Yes, I got the idea about this interpretation  right after posting (BTW it should '++q' vs 'q++') ...
In the  end should be expanded to autoincrementing address mode, in case of x86 the equivalent would be "string" ops.
>
> In this case the overall semantics are identical but your expandation looks like gdc's and mine like dmd's. Therefore I think dmd's is more correct although less useful.
>
> Generally I think it should just be an error to assign twice in the same expression.
>
Why not ? I kind of liked this one:
a = b = 0;

> Mafi

-- 
Dmitry Olshansky

« First   ‹ Prev
1 2