C - Why am I = ++ I causing undefined behavior?

I understand that C uses the concept of sequence points to identify ambiguous computations and that an operator is =

not a sequence point. However, I don't see any ambiguity when executing the instruction

i = ++i

According to my understanding, it just comes down to evaluating what is in &i

, increasing it and keeping it in one place. However, GCC refers to this as:

[Warning] operation on "i" can be undefined [-Wsequence-point]

Am I missing something about how functions =

?

EDIT: Before marking as a duplicate, please note that I was looking at other posts about sequence points and undefined. None of these are expression specific i=++i

(note the pre-increment). The above expressions are usually i=i++

, a=b++ + ++b

etc. And I have no doubts about any of them.

+3


source to share


2 answers


You are missing something about undefined behavior. The undefined behavior simply means that the compiler can do whatever it wants. This can cause an error, it can (like GCC) show a warning, it can cause demons to fly out of your nose. The main thing is that it won't behave well, and it won't behave consistently between compilers, so don't do that!

In this case, the compiler does NOT need to make a garentee that the side effects of the lhs statement must be completed before the rhs statement is returned. This sounds funny to you, but you don't think like a computer. He could, if he wanted, compute the return value and put it back in a register, assign it to i, and then increment the actual value. So it will be more like



register=i+1;
i=register;
i=i+1;

      

The standard doesn't give you a guarantee that it won't, so just don't!

+4


source


The undefined behavior occurs because a variable i

changes more than once between two points . Sequence points are points beyond which all side effects of previous assessments are visible, but no visible future side effects are observed. Standard states:

Between the previous and next point in the sequence, the object must have its saved value changed at most once by evaluating expression. In addition, the previous value must be read only to determine the value to be stored.

So what are the side effects that bother us?

  • ++i

    which assigns i the value i+1

  • i = ++i

    which assigns i the value of the expression ++i

    thati+1

So we're going to get two (admittedly equivalent) side effects: i+1

variable assignment i

. What worries us between which two side effects arise?

What operations are sequence points? There are several, but there is only one that really matters here:

  • at the end of a complete expression (in this case, it i = ++i

    is a complete expression)


Namely, the pre-increment is ++i

not a sequence point . This means that both side effects (increment and assignment) will occur between the same two points in the sequence, modifying the same variable i

. So this behavior is undefined; the fact that both modifications have the same meaning is immaterial.


But why is it bad to change a variable multiple times between sequence points? To prevent things like:

i = ++i + 1;

      

It is i

incremented here , but then it is also assigned a value (i+1) + 1

due to pre-increment semantics. Since side effects are of ambiguous order, the behavior is undefined.

Now, hypothetically, there might be a special case, made in the standard, that multiple modification between two sequence points is OK as long as the values ​​are the same, but that probably doesn't require unnecessarily complicated compiler implementations without much benefit.

+2


source







All Articles