Sequence Points and Side Effects in C

In this C-FAQ, he gives a sequence of points ;

The standard states that; Between the previous and the next point in the sequence, the object must have a value that its stored value is changed no more than once by evaluating the expression. In addition, the previous value should only be accessed to determine the value to be stored.

In the examples

i = i++; a[i] = i++; 

the first sentence of the statement shows that these examples are the result of undefined behavior.
In explaining the second sentence of the statement, it is said that;

Second sentence

states: if an object is written in full expression, any access to it within the same expression should be directly involved in calculating the value that must be written. This rule effectively limits legal expressions to those in which access is clearly preceded by modification. For example, the old standby mode

  i = i + 1 

allowed since access i is used to determine the final value of i. Example

 a[i] = i++ 

It is forbidden, because one of the calls I (the one in [i]) has nothing to do with the value that ends up being stored in I (what happens in I ++), and therefore there is no good way to determine.

My questions:
1. What does this mean if an object is written in a full expression, all and all calls to it inside the same expression should be directly involved in the calculation of the value to be written. ?

2. what does this mean: the example a[i] = i++ forbidden because one of the calls I (the one in [i]) has nothing to do with the value that ends up being stored in I (what happens in i + +)
Can someone explain this in a simple way?

+6
c undefined-behavior sequence-points
Jul 04 '13 at 15:15
source share
3 answers

Finally, I got an explanation about this. After reading and FAQ, I concluded that;

1. Last sentence

In addition, the previous value should only be accessed to determine the value to be stored.

will be like this:

In addition, the first value of the object should be accessed only to determine the value of the changed / new ( the same object ) to be saved.

As seen in the example

  int i = 1, j, a[5]; i = i + 1; j = i + 1; a[i] = i; 

in the case of the expression i = i + 1 previous value (which is 1 here) i (in RHS) is available to determine the value of i to be stored, and this is what the operator

if the object is written within the full expression, any access to it inside the same expression should be directly involved in calculating the value that should be written,

He speaks.
If, in the case j = i + 1 and a[i] = i available value of i is just the value not , no, where i varies in these operators.

2. The second question can be explained as follows: In the case of the expression a[i] = i++ or a[i++] = i first sentence of the above statement

Between the previous and the next point in the sequence, the object must have a value that its stored value is changed no more than once by evaluating the expression.

could not be obtained , since i changes only once between two consecutive points of the sequence. And so we need a second sentence.
Both of these examples are forbidden in C because the previous value of i accessed twice, i.e. i++ itself gets access to the previous value of i in the expression to change it and, therefore, other access to the previous value / value of i useless, since it is not accessed to determine the changed value that needs to be saved.

+1
Jul 13
source share

My question is: 1. What does it mean: if an object is written in a full expression, any access to it within the same expression should be directly involved in calculating the value that should be written.?

With a sub-expression of type i++ , i written to. In addition, assignment is an expression, therefore, in i = 2 , i written to. It may not be immediately obvious that a = b is an expression, but it is. That's why you can do things like a = b = c , which is good, and if (a = b) , which is less useful.

So he says that if you write on i , c = either before or after the increment, then any access to i should be as part of computing the new value of i. However, and this is important, the only thing related to the calculation of pre and post increment is the value of i at the beginning of the statement .

2. what does this mean: the example a [i] = i ++ is forbidden, since one of the calls i (the one in [i]) has nothing to do with the value that ends in i (which happens in i ++ )

Exactly what he says. When you access i in a[i] , this is not part of the calculation of the new value of i that is obtained from i++ .

Can someone explain this in a simple way?

A simple way: do not use a preliminary or lean increment in the expression. always use them in your applications. If you really really have to, DO NOT use the same variable anywhere else in the whole expression .

+6
Jul 04 '13 at 16:41
source share

This explanation is strange, and I cannot understand it.

The true explanation is that the expression i++ has a side effect (incrementing i ) that can be applied at any time after this particular i been evaluated.

Since outside the sequence points the C-language does not guarantee the evaluation order or the time of applying the post-increments (probably for performance reasons), in the second example three things can happen (suppose i = 5 before the line):

  • First, the left-most i (one in a[i] ) is processed to calculate the storage address [i]. Then the rightmost i is evaluated, then a post-increment is applied: the line executes a[5] = 5; i=6; a[5] = 5; i=6;
  • First, the rightmost i is selected, then the leftmost, and then i is applied a post-increment when everything is said and executed: in this case, the effects are identical to the case described above.
  • First, the rightmost i is evaluated, then a post-increment is applied, and then the leftmost i calculated to calculate the address [i] for storage. This time the effect a[6] = 5; i=6 a[6] = 5; i=6 .

The choice of the result depends not only on the choice of the compiler, but also on the compiler option: Microsoft Visual C ++ can give different results depending on whether you are compiling in Debug or Release.

+3
Jul 04 '13 at 15:27
source share



All Articles