In longobject.c we have the following usage a few times:
PyObject *
PyLong_FromLong(long ival)
{
PyLongObject *v;
// ... more locals ...
CHECK_SMALL_INT(ival);
if (ival < 0) {
/* negate: can't write this as abs_ival = -ival since that
invokes undefined behaviour when ival is LONG_MIN */
abs_ival = 0U-(unsigned long)ival;
sign = -1;
}
else {
// ... etc. etc.
The CHECK_SMALL_INT macro contains a `return`, so the function can actually return before it reaches any of the other code.
#define CHECK_SMALL_INT(ival) \
do if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) { \
return get_small_int((sdigit)ival); \
} while(0)
That's not even an error condition -- in fact it's the fast, hopefully reasonably-common, path.
An implicit return like this is pretty surprising for the reader. And it only takes one more line (plus a close-brace) to make it explicit:
if (IS_SMALL_INT(ival)) {
return get_small_int((sdigit)ival);
}
so that seems like a much better trade.
Patch written, will post shortly. |