Old bug in longobject.c + fix

Tim Peters tim.one at comcast.net
Mon Aug 19 16:42:13 CEST 2002

[Duncan Booth]
> I'm not entirely sure that I've got this right, but my reading of
> the code is this:
> a->ob_digit[j] is an unsigned short. When you try to left shift it, it
> is autmoatically promoted to unsigned int.

Not necessarily:  unsigned short promotes to signed int *if* the platform
int is capable of representing all platform unsigned short values.  This is
the case on most boxes.  Try this on a normal <wink> 32-bit box to see the

#include <stdio.h>

void main() {
    printf("%g\n", (double)((unsigned short)1 << 31));

Change "short" to "int" and the sign of the output should change.  But note
that the effect of this code is formally undefined (C doesn't define what
happens for left shifts or right shifts of a negative int, or for left lefts
of a positive int when the shift count is such that information is lost --
the full rules are even hairier).  Yet in practice most of that doesn't

> accum is of type unsigned long and the cast that the OP wants to add
> will force the original value to be promoted to unsigned long and
> shifted as one.
> On many systems you can expect the C types unsigned short to be 16 bits,
> unsigned int 32 bits and unsigned long 32 bits. When this is the
> case, the cast has no detectable effect. Therefore on most systems the
> bug is completely undetectable.

This is so, but for more complicated reasons.  It also works fine on Python
platforms where shorts, ints and longs are all 64 bits.

> However, it is possible that unsigned int is 16 bits, in which case the
> left shift will lose significant bits that should be preserved.
> The cast is required to prevent this happening.
> ...
> Would anyone care to list some systems which run Python and where the C
> 'int' type is represented on only 16 bits?

There aren't any, and Python would be severely broken for many reasons on
any such box (e.g., refcounts are stored in an int-sized field, and internal
errors would be rampant as refcounts overflowed 15 bits).

> ...
> I suspect though that the developers have better things to do with
> their time than try to deduce the reasoning behind the patch.

Well, it was obvious enopugh to me (& I believe I noticed it in 1992
<wink>), but I've got more pressing things to do than fix non-problems; if
the OP really cares about this, he should submit a patch that fixes *all*
the places this is done (the one he found isn't unique).  I don't care about
it enough to do that myself -- it seems purely academic.  If there's a box
out there where the result actually changes, then I would care.

More information about the Python-list mailing list