gnometorule
gnometorule

Reputation: 2139

Clarification c./ change in wording of C99 standard

I realize that merely asking about undefined behavior leads to downvotes by some, but I have a question comparing C99 v. Sep 2007 (the only one I have access to, and which so matters to me), and the one from 2011. The relevant quotes are from 6.5 (2) in either version:

2007: "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. (highlight added)"

2011: "If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the same scalar object, the behavior is undefined. (...)"

An example given to illustrate what contradicts this in the 2007 version is:

i = ++i + 1;    

As C considers an assignment always an expression (no assignment statements), this expression is semantically delineated by 2 sequence points. It is fairly obvious that both versions declare the above to result in undefined behavior.

However, given the highlighted sentence of the 2007 version, it would be my understanding that even the following expression (lying again between two sequence points) would result in undefined behavior:

  ++i; // or i++;  or a = ++i;   

, clearly, the "value to be stored" is not only read ('stored' is a bit ambiguous, but I would naturally read it as the one read): it is read, incremented, then stored back. It is sequenced though, and so fine (as it probably should be) by the 2011 wording.

Was this adjustment to the wording made to address the above, in order to match intent to description?

Note: I realize that to an extent this is opinion-based, but (1) the best-case would be that someone actually involved in writing the standard sees this, and (2) while I believe my interpretation to be reasonable/"true", if someone argues convincingly against it, this would be useful too.

Upvotes: 2

Views: 77

Answers (1)

haccks
haccks

Reputation: 106012

However, given the highlighted sentence of the 2007 version, it would be my understanding that even the following expression (lying again between two sequence points) would result in undefined behavior:

 ++i; // or i++;  or a = ++i;  

You understood wrong. This is best explained in c-faq question-3.8:

....And that's what the second sentence says: if an object is written to within a full expression, any and all accesses to it within the same expression must be directly involved in the computation of the value to be written. This rule effectively constrains legal expressions to those in which the accesses demonstrably precede the modification. For example, the old standby i = i + 1 is allowed, because the access of i is used to determine i's final value. The example

  a[i] = i++  

is disallowed because one of the accesses of i (the one in a[i]) has nothing to do with the value which ends up being stored in i (which happens over in i++), and so there's no good way to define--either for our understanding or the compiler's--whether the access should take place before or after the incremented value is stored.

In case of i++; or ++i; the access of i and its incrementation has to do with the value which ends up being stored in i.

Upvotes: 4

Related Questions