[OpenAFS-devel] Re: [OpenAFS] Volume root corruptions - anybody seen those? Explained and corrected

Jeffrey Hutzelman jhutz@cmu.edu
Tue, 12 Aug 2008 12:28:59 -0400


--On Tuesday, August 12, 2008 04:39:26 PM +0200 Rainer Toebbicke 
<rtb@pclella.cern.ch> wrote:

> On 64-bit machines SplitInt64 shifts the operand 32 bits to the right in
> order to isolate the high-order 32-bit word. If the operand itself is a
> 32-Bit integer (as is the case with "Length()" in vol-salvage.c), the
> behaviour is undefined according to the C standard! What gcc makes out of
> it is careless or at least unhelpful in my humble opinion, but who am I
> to criticize: it shifts the operand by 32 bits, forgetting that on Intel
> the shift counter is taken modulo 32 (in 32-bit mode), hence the shift is
> a no-op. On SPARC the same thing happens, but here it is (odd enough) the
> Sun compiler who shifts by modulo 32. Probably I am alone in regretting
> that given that both got worried to the point of issuing a warning,
> neither chose the solution closest to the underlying mathematical
> principle, anything resembling 32 divisions by 2...

This is entirely appropriate.  When the C standard says that the behavior 
in a particular situation is undefined, it does _not_ mean that the 
compiler should try to do something useful/meaningful/pleasing.  In fact, 
it almost always means that the compiler is expected to do whatever is most 
convenient for it, and that that is expected to differ significantly 
depending on the architecture and/or the compiler design.

In this case, leaving the behavior of a too-large shift undefined in the 
standard allows the compiler to use the CPU's bit-shift instruction, even 
when that instruction does something non-useful with a too-large shift.  If 
the standard required the behavior you describe, then the compiler would 
have to check and possibly adjust every shift count.  Worse, it would have 
to emit code to check and adjust shift counts that cannot be determined at 
compile time.

-- Jeff