[Python-Dev] New poll about a macro for safe reference replacing

Random832 random832 at fastmail.com
Wed Dec 16 09:53:52 EST 2015


Serhiy Storchaka <storchaka at gmail.com> writes:
> I'm bringing this up again, since the results of the previous poll did
> not give an unambiguous result. Related links: [1], [2], [3], [4].
>
> Let me remind you that we are talking about adding the following
> macro. It is needed for safe replacement links. For now there is at
> least one open crash report that can be solved with this macro [5] (I
> think there is yet one, but can't find it just now). And 50 potential
> bugs for which we just still do not have a reproducer.
>
> #define Py_XXX(ptr, value)        \
>     {                             \
>         PyObject *__tmp__ = ptr;  \
>         ptr = new_value;          \
>         Py_DECREF(__tmp__);       \
>     }

At the risk of bikeshedding, this needs do { ... } while(0), or
it almost certainly will eventually be called incorrectly in an
if/else statement.  Yes, it's ugly, but that's part of the cost
of using macros.

If it were implemented as below, then it could evaluate ptr only
once at the cost of requiring it to refer to an addressable
pointer object:
    PyObject **__tmpp__ == &(ptr);
    PyObject *__tmp__ = *__tmpp__;
    *__tmpp__ = (new_value);
    PY_DECREF(__tmp__);

I'm not entirely sure of the benefit of a macro over an inline
function.  Or why it doesn't INCREF the new value, maintaining
the invariant that ptr is an owned reference.

> 1. Py_SETREF
> 2. Py_DECREF_REPLACE
> 3. Py_REPLACE
> 4. Py_SET_POINTER
> 5. Py_SET_ATTR
> 6. Py_REPLACE_REF

I think "SET" names imply that it's safe if the original
reference is NULL. This isn't an objection to the names, but if
it is given one of those names I think it should use Py_XDECREF.



More information about the Python-Dev mailing list