The following statement is compiled incorrectly:
*p++ = ( *p>>n ) + !!( *p & (1<<(n-1)) ); /* unsigned *p,n */
(first left term calculated, then p is incremented, and for
right term incremented value of p used; result is stored at
the place p pointed before, however)
The fragment '(x>>n)+!!(x&(1<<(n-1)))' rounds x discarding n bits;
it is correct regardless of what may be said about style.
Equivalent form '(x>>n)+(x&(1<<(n-1)))?1:0' with *p++ from the
left of assignment is compiled correctly, what is a possible
workaround (besides obvious separation of ++ and assignment, what
of course works).
Unless I've misunderstood the ANSI C standard completely (which I assume
unlikely, given the amount of time I spent on thinking this over), this
is not a bug in DJGPP, nor in gcc. The given line of code is incorrect
C, as it relies on assumptions that do not hold.
To be more specific: the standard explicitly leaves it unspecified when
the side effect of the expression 'p++' happens, other than that it
must happen after the beginning of execution of the line of code shown,
and before execution of the next line of code.