[New-bugs-announce] [issue27725] Use Py_SIZE(x) instead of x->ob_size
REIX Tony
report at bugs.python.org
Wed Aug 10 05:51:37 EDT 2016
New submission from REIX Tony:
I'm porting Python 2.7.* on AIX.
I am now using a version 13.1.3.2 of XLC.
I was previously using version 12.1.0.14 .
It appears that this new compiler shows a potential issue in Python v2 code. This issue seems to appear when -O2 is used.
I was porting Python 2.7.11 with -O2 instead of -O0 when I got it.
The issue appears when running tests involving power() with Decimals where the x_sub() routine is used.
The following Python code shows the issue:
from decimal import *
c = Context(7, ROUND_UP)
d = c.power(Decimal(0.7), Decimal(3.4))
print d
Good result is: 0.2973948 .
The bug returns: 2.440099
However, I have about 22 errors when running:
./python Lib/test/regrtest.py -v test_decimal
It is random in 64bit and quite constant in 32bit.
The issue deals with using x->ob-size.
There is a macro:
Include/object.h:#define Py_SIZE(ob) (((PyVarObject*)(ob))->ob_size)
The issue appears in last lines of Objects/longobject.c:x_sub() routine, when changing the sign: z->ob_size = -(z->ob_size);
I have looked at version 2.7.12 and 2.7.10 of Python: they contain the same code as in 2.7.11.
And ->ob_size is used about 45 times, mainly in Objects/longobject.c. However, Py_SIZE(...) is used ten times more (475).
- Looking at version 3.5.1 of Python, I see that ->ob_size is now used only once, in: Objects/object.c .
And Py_SIZE(...) is now used 616 times.
And I also see that the Python 2.7.11-12 x_sub() code:
if (sign < 0)
z->ob_size = -(z->ob_size);
return long_normalize(z);
has been replaced in Python 3.5.1 by:
if (sign < 0) {
_PyLong_Negate(&z);
if (z == NULL)
return NULL;
}
return long_normalize(z);
/* If a freshly-allocated int is already shared, it must
be a small integer, so negating it must go to PyLong_FromLong */
Py_LOCAL_INLINE(void)
_PyLong_Negate(PyLongObject **x_p)
{
PyLongObject *x;
x = (PyLongObject *)*x_p;
if (Py_REFCNT(x) == 1) {
Py_SIZE(x) = -Py_SIZE(x);
return;
}
*x_p = (PyLongObject *)PyLong_FromLong(-MEDIUM_VALUE(x));
Py_DECREF(x);
}
So, it looks to me that Python v2 version should do the same that Python v3 has done: replace x->ob-size by Py_SIZE(x) everywhere, and improve the code of x_sub() by using some _PyLong_Negate() routine or macro.
----------
components: Library (Lib)
messages: 272324
nosy: trex58
priority: normal
severity: normal
status: open
title: Use Py_SIZE(x) instead of x->ob_size
type: behavior
versions: Python 2.7
_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue27725>
_______________________________________
More information about the New-bugs-announce
mailing list