[issue43502] [C-API] Convert obvious unsafe macros to static inline functions

STINNER Victor report at bugs.python.org
Mon Mar 15 10:17:22 EDT 2021


STINNER Victor <vstinner at python.org> added the comment:

I would add that we should pay attention to:

* not introducing a backward incompatible C API change by mistake
* not introducing new compiler warnings.

A common source of warning is that macros have no type for their arguments or return value, whereas static inline functions are strictly types. A common pattern in the Python header file is to use _PyObject_CAST() or _PyObject_CONST_CAST(). Example:

#define _PyObject_CAST(op) ((PyObject*)(op))
#define _PyObject_CAST_CONST(op) ((const PyObject*)(op))

static inline void _Py_INCREF(PyObject *op) { (...) }
#define Py_INCREF(op) _Py_INCREF(_PyObject_CAST(op))

For macros of the *internal* C API, it's ok to becom more strict about types. For example, in the *public* C API, I replaced:

#define PyObject_INIT(op, typeobj) \
    ( Py_TYPE(op) = (typeobj), _Py_NewReference((PyObject *)(op)), (op) )

with:

PyAPI_FUNC(PyObject *) PyObject_Init(PyObject *, PyTypeObject *);
#define PyObject_INIT(op, typeobj) PyObject_Init(_PyObject_CAST(op), (typeobj))

But for the internal C API, I added:

static inline void _PyObject_Init(PyObject *op, PyTypeObject *typeobj) { ... }

which doesn't cast its arguments.

----------

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue43502>
_______________________________________


More information about the Python-bugs-list mailing list