mirror of
https://github.com/python/cpython.git
synced 2025-09-26 10:19:53 +00:00
The Py_CLEAR(), Py_SETREF() and Py_XSETREF() macros now only evaluate their arguments once. If an argument has side effects, these side effects are no longer duplicated. Use temporary variables to avoid duplicating side effects of macro arguments. If available, use _Py_TYPEOF() to avoid type punning. Otherwise, use memcpy() for the assignment to prevent a miscompilation with strict aliasing caused by type punning. Add _Py_TYPEOF() macro: __typeof__() on GCC and clang. Add test_py_clear() and test_py_setref() unit tests to _testcapi.
This commit is contained in:
parent
7031275776
commit
b11a384dc7
7 changed files with 236 additions and 30 deletions
|
@ -7,8 +7,8 @@
|
|||
Reference Counting
|
||||
******************
|
||||
|
||||
The macros in this section are used for managing reference counts of Python
|
||||
objects.
|
||||
The functions and macros in this section are used for managing reference counts
|
||||
of Python objects.
|
||||
|
||||
|
||||
.. c:function:: Py_ssize_t Py_REFCNT(PyObject *o)
|
||||
|
@ -129,6 +129,11 @@ objects.
|
|||
It is a good idea to use this macro whenever decrementing the reference
|
||||
count of an object that might be traversed during garbage collection.
|
||||
|
||||
.. versionchanged:: 3.12
|
||||
The macro argument is now only evaluated once. If the argument has side
|
||||
effects, these are no longer duplicated.
|
||||
|
||||
|
||||
.. c:function:: void Py_IncRef(PyObject *o)
|
||||
|
||||
Increment the reference count for object *o*. A function version of :c:func:`Py_XINCREF`.
|
||||
|
@ -139,3 +144,40 @@ objects.
|
|||
|
||||
Decrement the reference count for object *o*. A function version of :c:func:`Py_XDECREF`.
|
||||
It can be used for runtime dynamic embedding of Python.
|
||||
|
||||
|
||||
.. c:macro:: Py_SETREF(dst, src)
|
||||
|
||||
Macro safely decrementing the `dst` reference count and setting `dst` to
|
||||
`src`.
|
||||
|
||||
As in case of :c:func:`Py_CLEAR`, "the obvious" code can be deadly::
|
||||
|
||||
Py_DECREF(dst);
|
||||
dst = src;
|
||||
|
||||
The safe way is::
|
||||
|
||||
Py_SETREF(dst, src);
|
||||
|
||||
That arranges to set `dst` to `src` _before_ decrementing reference count of
|
||||
*dst* old value, so that any code triggered as a side-effect of `dst`
|
||||
getting torn down no longer believes `dst` points to a valid object.
|
||||
|
||||
.. versionadded:: 3.6
|
||||
|
||||
.. versionchanged:: 3.12
|
||||
The macro arguments are now only evaluated once. If an argument has side
|
||||
effects, these are no longer duplicated.
|
||||
|
||||
|
||||
.. c:macro:: Py_XSETREF(dst, src)
|
||||
|
||||
Variant of :c:macro:`Py_SETREF` macro that uses :c:func:`Py_XDECREF` instead
|
||||
of :c:func:`Py_DECREF`.
|
||||
|
||||
.. versionadded:: 3.6
|
||||
|
||||
.. versionchanged:: 3.12
|
||||
The macro arguments are now only evaluated once. If an argument has side
|
||||
effects, these are no longer duplicated.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue