March 31, 2014
On 28 March 2014 22:12, Ali Çehreli <acehreli@yahoo.com> wrote:
> On 03/28/2014 03:05 PM, Timon Gehr wrote:
>
>> On 03/28/2014 10:56 PM, Ali Çehreli wrote:
>
>>> It is undefined behavior in both languages.
>>
>> How do you reach that conclusion in the case of D?
>
> By trusting my ignorance on such an execution order in D. :)
>
> Walter has been saying for a while that D will eventually make some execution orders standard (e.g. for function arguments). I would like to know if the situation has improved.
>

Regardless of what anyone says.  So long as this bug is open (linked),
then order of evaluation can only be regarded as undefined. :-)

http://bugzilla.gdcproject.org/show_bug.cgi?id=8

Regards
Iain.

March 31, 2014
Am Mon, 31 Mar 2014 18:00:07 +0100
schrieb Iain Buclaw <ibuclaw@gdcproject.org>:

> On 28 March 2014 22:12, Ali Çehreli <acehreli@yahoo.com> wrote:
> > On 03/28/2014 03:05 PM, Timon Gehr wrote:
> >
> >> On 03/28/2014 10:56 PM, Ali Çehreli wrote:
> >
> >>> It is undefined behavior in both languages.
> >>
> >> How do you reach that conclusion in the case of D?
> >
> > By trusting my ignorance on such an execution order in D. :)
> >
> > Walter has been saying for a while that D will eventually make some execution orders standard (e.g. for function arguments). I would like to know if the situation has improved.
> >
> 
> Regardless of what anyone says.  So long as this bug is open (linked),
> then order of evaluation can only be regarded as undefined. :-)
> 
> http://bugzilla.gdcproject.org/show_bug.cgi?id=8
> 
> Regards
> Iain.
> 

I have a fix + test cases for that issue for GDC btw (function call order, array op order, assignment order). But the frontend code changed between 2.064 and 2.065 (visitor related) so I'll port it to 2.065 first, then merge it into dmd and probably only merge back into gdc after the 2.065 frontend has been merged.

March 31, 2014
On Monday, 31 March 2014 at 16:18:13 UTC, Dominikus Dittes Scherkl wrote:
> (btw. I would _never_ever_ write a line like "i++;" That's garbage. It should always be "++i;"
> Yes, the optimizer will get rid of the temporary variable, but it is absolutely unintuitive (if I read something like that my first thought is: what is the
> old value used for? Why using a temporary variable?)

Using "i++" can make a lot of sense, especially when you are iterating indexes. Very often, you want the data *at* i, and then you want to increment i. It makes sense to write "p[i++]", and avoids writing an extra instruction.

A "famous" example is the strcpy (example) implementation, which is just:
while(*dest++ = *src++);

You wouldn't write that with ++i.

> The post-increment has a much, much higher priority, so I would think it is obvious that first the value is incremented and afterwards the old value is assigned to it.
> And of course, the old, non-incremented value is assigned. This is the essence od POST incrementing - the return value of this operator is defined to be the old value, that's the whole point why this operator exists.

The issue at hand is that most compilers don't do "verbatim" what you type. They are actually allowed to do whatever the heck they want, provided the *observable* behavior is what you typed. This is good, because it allows them to take shorcuts, or "optimize".

The issue is, when they take these shortcuts, they assume (rightfully) that your code conforms to spec. If not, then "undefined behavior" is what happens.

i = i++;

This does not conform to spec because "i" is written to and read to, all in between two sequence points. This is illegal, and produces undefined behavior.

Here is how it can happen:
=> Compiler reads "i =". Thinks "OK, I need to assign something to i".
=> Then reads "operator++(i)". Thinks, "OK, I need to assign the result of that to i".
=> Then thinks "I know what the result of i++ is, and i++ isn't legally allowed to modify i, since I just read it"
=> Compiler "assigns i to i" (value is unchanged)
=> Compiler executes i++ (value is incremented).

Here is another fun story. I once encountered this code.
i = ++i;
With the right compiler options, the result was that 'i' was incremented... twice!

Go! Go! Undefined behavior!
March 31, 2014
On Monday, 31 March 2014 at 18:16:32 UTC, monarch_dodra wrote:
> On Monday, 31 March 2014 at 16:18:13 UTC, Dominikus Dittes Scherkl wrote:
>> (btw. I would _never_ever_ write a line like "i++;" That's garbage. It should always be "++i;"

> Using "i++" can make a lot of sense, especially when you are iterating indexes.
Of course the post-increment is often very usefull - iff you use
it's return value. Therefore the semicolon.
i++;
as a whole line is very bad style, I think.

> i = i++;
>
> This does not conform to spec because "i" is written to and read to, all in between two sequence points. This is illegal, and produces undefined behavior.
Why?
If the operators had the same precedence, ok.
But ++ has to come first (no matter if post or pre).
something like
j = --i++;
yeah, that is undefined (pre- and post having same priority).

But does the spec really say a value may not at the same time be read from and written to? Then i=i; would also be illegal. And how about i += i; ? I think this is allowed and useful, ne?
What about i = ++i; (ok does nothing diffrent from ++i; but is still ok and not a NOP)?

i = i++; is unambigous if the compiler doesn't optimize it. And if it optimizes, it should replace it by NOP.
But it is likely that this is a typo or a logic-bug by the user, so the compiler should instead warn or even forbid it.

As a general rule in one expression one variable should not be
allowed to be modified more than once.

e.g.
i++ = i;
j = i++ / i++;
i += i++;
etc. should all be forbidden.

> Go! Go! Undefined behavior!

1 2 3 4
Next ›   Last »