4

I was reading through K&R and i came across this example about uncertainty in behavior while evaluating expression like a[i]=i++; The C99 spec in $6.5.2 says that

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 read only to determine the value to be stored.

The above example from K&R holds good on the first statement. Please explain how does it fail on the second.

Does standard says anything about the order of evaluation of sub-expressions in case of the sequence points being involved. Eg. a[i++] || b[i++]. I know that these are evaluated from left to right but how can this be derived from the above statement or is it explicitly stated in the standard somewhere ?

Bazooka
  • 1,428
  • 4
  • 15
  • 24
  • possible duplicate of [Any good reason why assignment operator isn't a sequence point?](http://stackoverflow.com/questions/4362501/any-good-reason-why-assignment-operator-isnt-a-sequence-point) – Suma Jan 30 '12 at 08:35
  • 1
    possible duplicate of [Undefined Behavior and Sequence Points](http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points) – Lundin Jan 30 '12 at 13:25
  • @undur_gongor As far as I know, there is no difference between C and C++ when it comes to sequence points and order of evaluation. – Lundin Jan 30 '12 at 13:44
  • @Lundin: Then, this could be part of a good answer. Still, the question is not a duplicate. – undur_gongor Jan 30 '12 at 14:00
  • @undur_gongor Oh please, we get at least five `i+++++i` questions per week. As for the specific case of why the assignment operator isn't a sequence point, someone else linked a post to that as well. – Lundin Jan 30 '12 at 14:51
  • http://stackoverflow.com/questions/949433 might be the "biggest" C-focussed member of this dupe-cluster – Steve Jessop Apr 16 '13 at 12:57

2 Answers2

4

Does standard says anything about the order of evaluation of sub-expressions in case of the sequence points?

The order of evaluation is well defined in case of conditional operators && as well as || and that is the very reason short circuiting works.

It is explicitly specified by the c99 standard.

Reference: c99 Standard

Annex J: J.1 Unspecified behavior

1 The following are unspecified:
.....

The order in which subexpressions are evaluated and the order in which side effects take place, except as specified for the function-call (), &&, ||, ?:, and comma operators (6.5).
.....

Further in,
6.5.14 Logical OR operator

4) Unlike the bitwise | operator, the || operator guarantees left-to-right evaluation; there is a sequence point after the evaluation of the first operand. If the first operand compares unequal to 0, the second operand is not evaluated.

As well as for logical AND:

6.5.13 Logical AND operator

Unlike the bitwise binary & operator, the && operator guarantees left-to-right evaluation; if the second operand is evaluated, there is a sequence point between the evaluations of the first and second operands. If the first operand compares equal to 0, the second operand is not evaluated.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
  • 1
    Thanks but can you please provide some explanation about the the first question i asked about a[i]=i++; – Bazooka Jan 30 '12 at 08:01
  • @Parminder assignment operator is not a sequence point in C. Note: C++11 introduces a concept of sequenced before / after, and a[i]=i++ is [well defined in C++11](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2239.html). See also http://stackoverflow.com/questions/4362501/any-good-reason-why-assignment-operator-isnt-a-sequence-point – Suma Jan 30 '12 at 08:35
  • AWESOME ANSWER! This helped me with `a || b++ && c` to know if `b++` is always evaluated. It does not, but the higher precedence of the &&-operator will draw an argument from a lot of people claiming otherwise. – Kevin P. Rice Jul 16 '12 at 09:13
0

For the first part of the question:

The sentence applies to objects being changed by the expression, i.e. i (and a[i]). So, the prior value of i shall be used exclusively to determine the "new" value for i.

But the expression "uses" it also to determine the array element to be written to.

The background is that otherwise it would be unclear if i denotes i's value before or after the increment.

undur_gongor
  • 15,657
  • 5
  • 63
  • 75
  • Thanks but I have another doubt with regards to this. An expression like `++i==i` seems to be ambiguous at the first glance. But it is not trying to "change" anything except i. So is this undefined behavior too ?? – Bazooka Jan 30 '12 at 13:05
  • I'm not trying to change any lvalue. All I'm trying to say is that while evaluating from right to left i'm changing `i` only once and when i access `i` for the second time i do so to change on the value of `i` itself. This confirms to the second statement i guess. So whats the problem ? Is this is a legit Expression with a definite behavior ? – Bazooka Jan 30 '12 at 13:22
  • There is no re-assignment taking place, only the increment operation. This is `==` not `=`, just in case you missed. – Bazooka Jan 30 '12 at 13:33
  • Sorry, I must be blind. But then, you are using the value of the object `i` being changed not only for calculating `i`'s new value but also for the comparison. Thus, you are violating the very same constraint as in your question. – undur_gongor Jan 30 '12 at 13:36
  • 1
    i think i get i now. The expression is undefined because `Any access to an object that is being modified between two sequence points should be to change that object only and nothing else.` In this example we use it for comparison that mviolates the second "rule". But it still holds good on the first statement. Cheers !! – Bazooka Jan 30 '12 at 14:09