Warn about do nothing expressions?

monarch_dodra monarchdodra at gmail.com
Mon Mar 31 11:16:31 PDT 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!


More information about the Digitalmars-d mailing list