New submission from Hallvard B Furuseth <h.b.furus...@usit.uio.no>: 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 ---------- components: Interpreter Core messages: 120492 nosy: hfuru priority: normal severity: normal status: open title: PY_LLONG_MAX & co - preprocessor constants or not? type: compile error versions: Python 2.6, Python 2.7, Python 3.1, Python 3.2 _______________________________________ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue10325> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com