That's stupid. The right side of the expression must be evaluated before
an assignment can be made. Where is the ambiguity exactly?
++ is an operator. Unless optimized away (obviously not the case
here), the compiler generates code to perform the evaluation specified
by the operator. The result of evaluating a post ++ is the current
value of the operand.
But ++ also has a side effect. In this case it will increment the
value of its operand. The only thing you know about when this side
effect occurs is that it will occur at or before next sequence point.
There are two sequence points in the statement. One is when the
function tolower() is called. (Obviously, the argument must be
evaluated before the function can be called.) The second is at the
semi-colon.
Since there is no dependency/relationship between the evaluation of
the ++ and the function call, they can occur in either order.
(Consider the expression a+b+tolower(c). a+b can be evaluated before
or after tolower is called.)
If the function call occurs first, then the ++ will be evaluated
after the argument and there is no confusion.
If the ++ is evaluated first, then it could be evaluated before or
after the argument.
While unlikely, it is possible for the generated code to
evaluate the argument, then evaluate the ++, and then call the
function. Again in this case there is no confusion.
In the more likely case, the ++ will be evaluated before the
argument. Now the problem is we do not know when the side effect
occurs. Does it occur before or after the argument is evaluated?
To eliminate this ambiguity and to avoid restricting compilers that
generate code for parallel machines or other advanced architectures,
the standard states:
"Between the previous and next sequence point an object shall have its
stored value modified at most once by the evaluation of an expression.
Furthermore, the prior value shall be accessed only to determine the
value to be stored."
(It is the second sentence that the statement in question violates
since str is accessed for two purposes. On the left it is used to
determine the current value but on the right it is dereferenced to
provide the argument to tolower.)
The standard also provides two examples:
"This paragraph renders undefined statement expressions such as
i = ++i + 1;
a[i++] = i;
while allowing
i = i + 1;
a
= i;"
<<Remove the del for email>>