On Thu, Feb 10, 2022 at 10:58 AM Petr Viktorin <encu...@gmail.com> wrote:
>
> On 09. 02. 22 21:41, Gregory P. Smith wrote:
> >
> > On Wed, Feb 9, 2022 at 8:54 AM Victor Stinner <vstin...@python.org
> > Perhaps use a hybrid approach
> > when feasible similar to:
> >    #define PyUnicode_CHECK_INTERNED(op)
> > _PyUnicode_CHECK_INTERNED((PyASCIIObject *)(op))
> >
> > 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.
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-le...@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at 
https://mail.python.org/archives/list/python-dev@python.org/message/XOLV4BVJDZH3RJRLV3UKDYKA664IANZO/
Code of Conduct: http://python.org/psf/codeofconduct/

Reply via email to