[Python-Dev] [Python-checkins] r41972 - python/branches/ssize_t/Objects/funcobject.c

Tim Peters tim.peters at gmail.com
Mon Jan 9 00:47:12 CET 2006


[Tim]
>> That handles C99-ish platforms by defalt.  Other platforms (like
>> Windows) would need to supply their own expansion in their pyconfig.h.
>>  Neal's format would become the god-awful
>> but platform-neutral:
>>
>>           "%s() requires a code object with %" Py_SIZE_T_WIDTH "d free vars,"
>>           " not %" Py_SIZE_T_WIDTH "d"

[Martin]
> That's too ugly, IMO. So I could accept to write
>
>         "%s() requires a code object with %ld free vars,"
>         " not %ld", PyString_AsString(op->func_name),
>         (long)nclosure, (long)nfree);
>
> instead. Alternatively, if there is a real chance that it overflows
> LONG_MAX (which there isn't, AFAIK - we don't support that many free
> vars), we could also write
>
>         "%s() requires a code object with %ld free vars,"
>         " not %ld", PyString_AsString(op->func_name),
>         Py_long_ceil(nclosure), Py_long_ceil(nfree));
>
> with
>
> #define Py_long_ceil(n) ((n) > LONG_MAX ? LONG_MAX : \
>     (n) < LONG_MIN ? LONG_MIN : (n))
>
> On most platforms, the compiler should notice that the conditions
> are both known false, and collaps this to (n).
>
> If this ever overflows, somebody will have to remember that
> this is really +/- infinity.

I think you're trying to solve a different problem.  I'm not trying to
special-case the snot out of Neil's specific line of code, along the
lines of "well, yes, the types here were changed from int to
Py_ssize_t, but that was basically bizarre since in fact plain old int
was big enough to hold all plausible values to begin with, so let's
find a way to pass Py_ssize_t arguments in cases where they're really
ints or longs".  If that's what's going on here, it's a symptom of
changing type declarations with little thought just to shut up
compiler warnings.  If `int` or `long` are in fact big enough to hold
all plausible values for these variables, then that's what they should
be declared as.

The problem I am trying to solve is formatting values that are of
types size_t or Py_ssize_t for _good_ reason:  in effect, they really
need to be 64 bits on 64-bit boxes, and "unsigned long"/"long" aren't
good enough for that on all 64-bit platforms. In these cases, using
%ld is wrong, and truncating bits is also wrong.  These cases need a
platform-correct format code.  The pain of separating out the width
modifier could be reduced by defining a few type-oriented macros
instead; e.g.,

#define PyFORMAT_ssize_t "%zd"  /* on C99 boxes */

If it made sense to use Py_ssize_t to begin with in that code, then:

         "%s() requires a code object with " PyFORMAT_ssize_t " free vars,"
         " not " PyFORMAT_ssize_t, PyString_AsString(op->func_name),
         nclosure, free);

That's no more or less painful than using C99's huge pile of PRId8,
PRId16, PRId32 (etc, etc) macros, defined there for similar purposes.


More information about the Python-Dev mailing list