On Thu, Feb 10, 2022 at 10:58 AM Petr Viktorin
On 09. 02. 22 21:41, Gregory P. Smith wrote:
On Wed, Feb 9, 2022 at 8:54 AM Victor Stinner
That should make it safe. And I believe you do mention this technique as something to be used in the PEP.
It is exactly what the PEP proposes in the Specification section to avoid adding new compiler warnings: https://www.python.org/dev/peps/pep-0670/#cast-to-pyobject Macro which is only there to add the cast, to avoid adding a compiler warning: #define Py_TYPE(ob) _Py_TYPE(_PyObject_CAST_CONST(ob)) Static inline function: static inline PyTypeObject* _Py_TYPE(const PyObject *ob) { ... } Use the existing macro to do the cast: #define _PyObject_CAST_CONST(op) ((const PyObject*)(op))
That technique is mentioned in the PEP, but it looks like we just found a better way to do it than what the PEP suggests: the macro and the function can have the same name
Well, when I started to convert macros to static inline functions, I chose to have a different name to help *me* identifying what is what: "Pyxxx" is the macro and "_Pyxxx" is the static inline functions. It looked convenient at the beginning. It looked like a good idea... Then I started to see "_Pyxxx" functions in debuggers and profilers. It's not convenient since in C extensions, the public "Pyxxx" (macro) name is used, same in old Python versions. Having a different name can cause practical issues: Lib/test/test_gdb.py and Tools/gdb/libpython.py have to search for multiple names for the same function in this case (to support old and new Python versions). The new private/secret "_Pyxxx" name is unexpected, so I proposed to abandon this bad habit and use the same name for the macro and for the static inline function.
Are there any downsides to that?
There is no downside. Macros are only for the C preprocessor, they are gone at the ABI level. The macro is just there to add a cast to avoid adding new compiler warnings (since the old macro already did that). Moreover, PEP 670 proposes to replace some static inline functions with regular functions to make them available for extension modules which cannot use static inline functions, like the vim text editor (written in C) which only loads symbols from libpython. Having a consistent name for macros, static inline functions and functions should help for that. -- There is one exception: when a function as exposed as static inline function *and* a regular function. _Py_Dealloc() and Py_NewRef() for example. Py_NewRef() is defined as a macro which calls _Py_NewRef() static inline function (for best performance), and there is a regular Py_NewRef() regular function (exposed in the ABI): the regular function and the static inline functions cannot have the same name: PyAPI_FUNC(PyObject*) Py_NewRef(PyObject *obj); static inline PyObject* _Py_NewRef(PyObject *obj) { Py_INCREF(obj); return obj; } #define Py_NewRef(obj) _Py_NewRef(_PyObject_CAST(obj)) Names: * Macro: Py_NewRef * Regular function: Py_NewRef * Static inline function: _Py_NewRef (different name) If _Py_NewRef() is renamed to Py_NewRef(), the compiler fails with: ./Include/object.h:597:25: error: static declaration of 'Py_NewRef' follows non-static declaration Another example is _Py_Dealloc() declared as a macro+static inline function (best performance) *and* a regular function (expose it in the ABI): the static inline function has a different name. IMO the most important name is the regular function name since it's the one which lands in libpython ABI. Static inline functions are *not* part of the libpython ABI, they are either inlined or copied as regular functions (depending on what the compiler prefers) in each extension module using it. Victor -- Night gathers, and now my watch begins. It shall not end until my death.