This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author hfuru
Recipients hfuru
Date 2010-11-05.13:56:09
SpamBayes Score 4.383952e-09
Marked as misclassified No
Message-id <1288965372.95.0.322439917087.issue10325@psf.upfronthosting.co.za>
In-reply-to
Content
Include/pyport.h invites potential compile errors with the definitions
  #define PY_LLONG_MIN LLONG_MIN
  #define PY_LLONG_MAX LLONG_MAX
  #define PY_ULLONG_MAX ULLONG_MAX
which can fall back to gcc variants or to
  #else
  /* Otherwise, rely on two's complement. */
  #define PY_ULLONG_MAX (~0ULL)
  #define PY_LLONG_MAX  ((long long)(PY_ULLONG_MAX>>1))
  #define PY_LLONG_MIN (-PY_LLONG_MAX-1)

Code developed with the former #definitions might use them in '#if's,
and then break when it meets a host where the fallbacks are used.

It would be safer if either all the macros and pyconfig variants used
casts, or all used predefined constants - from configure if needed.

The signed variants would break because '#if's do not accept casts.

PY_ULLONG_MAX is more insidious: If it meets a host which supports
a type bigger than unsigned long long, then preprocessor arithmetic
will happen in that type. ~0ULL in #if statements is then actually
the same as ~ULLL or whatever it would be spelled.  This one
definitely needs a cast to protect from the surprise that
preprocessor value != value outside preprocessor.

You get the same effect with ~0U vs ~0UL on a 64-bit compiler,
and ~0U vs ~0ULL on a C99 compiler:
#if (~0U) == (~0ULL)
# error "oops"
#endif

Incidentally, the "two's complement" comment is wrong.
It also relies on unsigned long long being widest type with no
padding bits, and -LLONG_MAX-1 not being a trap representation.
~0ULL is not two's complement since it is unsigned, it works
because it has the same result as -1ULL which is defined to
have the max value.
The PY_LLONG_MIN definitions rely on two's complement. If
anyone cared, one could avoid that with
#define PY_LLONG_MIN (-PY_LLONG_MAX-(/*two's complement*/(-1LL & 3)==3))


Anyway.  If they use casts, fix PY_TIMEOUT_MAX in 3.2a3 pythread.h:
#define PY_MIN(x, y) ((x) < (y) ? (x) : (y))
#define PY_TIMEOUT_MAXTMP instead of PY_TIMEOUT_MAX, and then
#ifndef NT_THREADS
#define PY_TIMEOUT_MAX PY_TIMEOUT_MAXTMP
#else
#define PY_TIMEOUT_MAX PY_MIN(Py_LL(0xFFFFFFFF)*1000, PY_TIMEOUT_MAXTMP)
#endif
History
Date User Action Args
2010-11-05 13:56:13hfurusetrecipients: + hfuru
2010-11-05 13:56:12hfurusetmessageid: <1288965372.95.0.322439917087.issue10325@psf.upfronthosting.co.za>
2010-11-05 13:56:11hfurulinkissue10325 messages
2010-11-05 13:56:09hfurucreate