View mode: basic / threaded / horizontal-split · Log in · Help
April 20, 2011
postincrement behaviour (differences between dmd and gdc)
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
Re: postincrement behaviour (differences between dmd and gdc)
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
Re: postincrement behaviour (differences between dmd and gdc)
> 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
Re: postincrement behaviour (differences between dmd and gdc)
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
Re: postincrement behaviour (differences between dmd and gdc)
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
Re: postincrement behaviour (differences between dmd and gdc)
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
Re: postincrement behaviour (differences between dmd and gdc)
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
Re: postincrement behaviour (differences between dmd and gdc)
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
Re: postincrement behaviour (differences between dmd and gdc)
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
Re: postincrement behaviour (differences between dmd and gdc)
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
Top | Discussion index | About this forum | D home