[sane-devel] C undefined operations in sane-backends-1.0.7-b
Ingo Wilken
Ingo.Wilken at Informatik.Uni-Oldenburg.DE
Thu Jan 24 14:19:31 GMT 2002
> i do no understand this discussion about the code fragment
> bit =3D ++bit % 8;
> 1. Since 20 years, C is my favorite programming language
> 2. Since some years, I give classes in C
> 3. The code line "bit =3D ++bit % 8", is fully correct.
No. 'bit' is modified twice between sequence points, so the behaviour
is undefined. See comp.lang.c FAQ, section 3.1, 3.2, 3.3, 3.3b, and
others. (http://www.faqs.org/)
Basically, the 'store' part of the pre-increment can happen any time
this expression is evaluated. C guarantees that 'bit' will be
incremented before the next sequence point and that it uses the
incremented value in the rest of the expression, but it does not say
that the incremented value gets stored to 'bit' immediately.
For example, the compiler can expand the expression to this:
tmp1 = bit; # Fetch into register
tmp1 = tmp1 + 1; # increment part of ++bit
tmp2 = tmp1 % 8; # rest of expression
bit = tmp2; # assignment
bit = tmp1; # store part of ++bit
or it can swap the last two lines (which is the desired result)
tmp1 = bit;
tmp1 = tmp1 + 1; # increment part of ++bit
tmp2 = tmp1 % 8; # rest of expression
bit = tmp1; # store part of ++bit
bit = tmp2; # assignment
or it can even do something like (assuming a register-starved CPU
with fast memory-to-memory operations):
tmp1 = bit; # Fetch into register
tmp1 = tmp1 + 1; # Increment register
tmp1 = tmp1 % 8; # rest of expression
bit = tmp1; # assignment
bit = bit + 1; # increment memory location
Depending on the machine architecture, it can even do the increment-store
in parallel with the other operations, so you might get a race condition
and partial writes from both store operations - or a CPU exception.
Anyway, the expression is easily fixed. Either use:
++bit;
bit %= 8;
or
bit = (bit+1) % 8;
Regards,
Ingo
More information about the sane-devel
mailing list