chiark / gitweb /
progs/..., symm/...: Fix 32-bit right-shift idiom.
authorMark Wooding <mdw@distorted.org.uk>
Tue, 30 Oct 2018 22:05:18 +0000 (22:05 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Sat, 24 Nov 2018 20:12:17 +0000 (20:12 +0000)
This one has a long and troubled history.  Writing

x >> 32

is undefined behaviour if x is only 32 bits wide.  On the other hand, if
it's /not/, then this is necessary to get hold of the upper bits.

The obvious escape plan is to write

(x >> 16) >> 16

(the parentheses are unfortunately necessary), but some Microsoft
compilers managed do bungle compiling this: they merged the two shifts
together and then decided that a shift by 32 places was a no-op.

So I wrote

((x&~MASK32) >> 16) >> 16

which stood for many years.  Unfortunately this is really wrong too: if
x is wider than 32 bits, that's nice, but MASK32 /isn't/ necessarily, so
~MASK32 is all-bits zero and the high bits of x are just lost.

Fix this by casting MASK32 to the-type-of-x before inverting it.

Ugh.


No differences found