Skip to content

Define _Py_TYPEOF on MSVC and other compilers supporting __typeof__ #121647

Open
@fuhsnn

Description

@fuhsnn

Feature or enhancement

Proposal:

Recently, MSVC implemented __typeof__, which currently is defined as _Py_TYPEOF only on GCC and Clang.

cpython/Include/pyport.h

Lines 553 to 560 in 65feded

// _Py_TYPEOF(expr) gets the type of an expression.
//
// Example: _Py_TYPEOF(x) x_copy = (x);
//
// The macro is only defined if GCC or clang compiler is used.
#if defined(__GNUC__) || defined(__clang__)
# define _Py_TYPEOF(expr) __typeof__(expr)
#endif

The only users of _Py_TYPEOF are macros Py_CLEAR(), Py_SETREF() and Py_XSETREF().
If _Py_TYPEOF is not defined, these macros fall back to slightly uglier implementations with memcpy calls.

cpython/Include/refcount.h

Lines 421 to 442 in 65feded

#ifdef _Py_TYPEOF
#define Py_CLEAR(op) \
do { \
_Py_TYPEOF(op)* _tmp_op_ptr = &(op); \
_Py_TYPEOF(op) _tmp_old_op = (*_tmp_op_ptr); \
if (_tmp_old_op != NULL) { \
*_tmp_op_ptr = _Py_NULL; \
Py_DECREF(_tmp_old_op); \
} \
} while (0)
#else
#define Py_CLEAR(op) \
do { \
PyObject **_tmp_op_ptr = _Py_CAST(PyObject**, &(op)); \
PyObject *_tmp_old_op = (*_tmp_op_ptr); \
if (_tmp_old_op != NULL) { \
PyObject *_null_ptr = _Py_NULL; \
memcpy(_tmp_op_ptr, &_null_ptr, sizeof(PyObject*)); \
Py_DECREF(_tmp_old_op); \
} \
} while (0)
#endif

The proposal is to define _Py_TYPEOF on:

  • latest MSVC versions that support __typeof__
  • arbitrary compilers that support __typeof__
  • arbitrary compilers that support C23 typeof or C++11 decltype

By defining _Py_TYPEOF, uses of Py_CLEAR(), Py_SETREF() and Py_XSETREF() are switched to the _Py_TYPEOF implementation; on these compilers, the benefits would be:

Additionally, this removes a differing detail between MSVC and GCC/Clang builds, which should be generally desirable.

Has this already been discussed elsewhere?

No response given

Links to previous discussion of this feature:

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions