Reputation: 48477
When the evaluation of l-value precedes the evaluation of r-value and the assignment also returns a value, which of the following is evaluated first?
int i = 2;
int x[] = {1, 2, 3};
int y[] = {4, 5, 6};
int z[] = {7, 8, 9};
x[--i] = y[++i] = z[i++]; // Out of bound exception or not?
NOTE: generic C-like language with l-value evaluation coming first. From my textbook:
In some languages, for example C, assignment is considered to be an operator whose evaluation, in addition to producing a side effect, also returns the r-value thus computed. Thus, if we write in C:
x = 2;
the evaluation of such a command, in addition to assigning the value 2 to x, returns the value 2. Therefore, in C, we can also write:
y = x = 2;
which should be interpreted as:
(y = (x = 2));
Upvotes: 1
Views: 1699
Reputation: 95385
I'm quite certain that the behaviour in this case is undefined, because you are modifying and reading the value of the variable i
multiple times between consecutive sequence points.
Also, in C, arrays are declared by placing the []
after the variable name, not after the type:
int x[] = {1, 2, 3};
Remove the arrays from your example, because they are [for the most part] irrelevant. Consider now the following code:
int main(void)
{
int i = 2;
int x = --i + ++i + i++;
return x;
}
This code demonstrates the operations that are performed on the variable i
in your original code but without the arrays. You can see more clearly that the variable i
is being modified more than once in this statement. When you rely on the state of a variable that is modified between consecutive sequence points, the behaviour is undefined. Different compilers will (and do, GCC returns 6, Clang returns 5) give different results, and the same compiler can give different results with different optimization options, or for no apparent reason at all.
If this statement has no defined behaviour because i
is modified several times between comsecutive sequence points, then the same can be said for your original code. The assignment operator does not introduce a new sequence point.
Upvotes: 6
Reputation: 28258
In C, the order of any operation between two sequence points should not be dependent on. I do not remember the exact wording from the standard, but it is for this reason
i = i++;
is undefined behaviour. The standard defines a list of things that makes up sequence points
, from memory this is
Looking up the page on wikipedia, the lists is more complete and describes more in detail. Sequence points is an extremely important concept in C and if you do not already know what it means, do learn it immediately.
No matter how well defined the order of evaluation and assignment of the x
, y
and z
variables are, for
x[--i] = y[++i] = z[i++];
this statement cannot be anything but undefined behaviour because of the i--
, i++
and i++
.
On the other hand
x[i] = y[i] = z[i];
is well defined, but I am not sure what the status for the order of evaluation for this. If this is important however I would rather prefer this to be split into two statements along with a comment "It is important that ... is assigned/initialized before ... because ...".
Upvotes: 2