[issue10325] PY_LLONG_MAX & co - preprocessor constants or not?

Hallvard B Furuseth report at bugs.python.org
Sat Nov 6 19:43:12 CET 2010


Hallvard B Furuseth <h.b.furuseth at usit.uio.no> added the comment:

Mark Dickinson writes:
> Thanks for the report; I agree that there's a potential issue here, and
> I also think that all these definitions *should* be preprocessor
> defines.

Indeed, my suggestion to castify everything for uniformity was silly: My
own PY_TIMEOUT_MAX fix illustrates why that won't promote portability.
It breaks code which #ifdefs between using LONG_MAX and PY_LLONG_MAX.

> (Idle question: does C99 require that LONG_MAX and friends are
> usable in the preprocessor?  ...)

5.2.4.2.1p1: Sizes of integer types <limits.h>.

> Can you suggest a suitable fix for the PY_ULLONG_MAX and PY_LLONG_MAX
> defines?  (...)

As far as I can tell, PC/pyconfig.h already solves it for Windows.

For pyport.h, since you do #define SIZEOF_LONG_LONG:

#define PY_LLONG_MAX \
    (1 + 2 * ((Py_LL(1) << (CHAR_BIT*SIZEOF_LONG_LONG-2)) - 1))
#define PY_ULLONG_MAX (PY_LLONG_MAX * 2ULL + 1)

You could check PY_ULLONG_MAX with a compile-time assertion if you want:

#ifndef __cplusplus /* this requires different magic in C++ */

/* Compile-time assertion -- max one per post-preprocessed line */
#define Py_static_assert(expr) Py_static_assert1_(expr, __LINE__)
#define Py_static_assert1_(expr, line) Py_static_assert2_(expr, line)
#define Py_static_assert2_(expr, line) struct Py_static_assert##line { \
	int Assert1_[(expr) ? 9 : -9]; int Assert2_: (expr) ? 9 : -9; }

Py_static_assert(PY_ULLONG_MAX == (unsigned long long)-1);

#endif /* __cplusplus */

> BTW, do you know of any modern non-Windows platforms that don't define
> LLONG_MIN and LLONG_MAX?  It may well be that the "two's complement"
> fallback hasn't been exercised in recent years.

Anyting compiled with strict ANSI pre-C99 mode, e.g. gcc -ansi, which
you do have a workaround for.  But gcc isn't the only one to be slow in
upgrading to C99.

And unfortunately, even if Python is built without a compiler's
equivalent of -ansi, a user embedding Python might be compiling with it.

Beyond that: No, I know none, but I don't know many platforms anyway.

>> 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.
> 
> Agreed---that comment needs to be better.  I think it's fine, though,
> for practical purposes to assume an absence of padding bits and no trap
> representation; IIRC there are places internally (e.g., in the bitwise
> operators section of the 'int' type implementation) that already assume
> two's complement + no padding bits + no trap representation.

I expect so, yes.  It's easy to find breakage with non-two's complement,
just grep the C code for '~'.  I just get peeved when people get this
wrong, then document and promote the errors:)

----------

_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue10325>
_______________________________________


More information about the Python-bugs-list mailing list