PyUnicode_READ() fails to build on C++: _Py_CAST() used with a constant type (const void*) · Issue #92800 · python/cpython (original) (raw)

Bug report

The new _Py_CAST macro (https://github.com/python/cpython/pull/91959/files, and other commits) designed to reduce C++ warnings adds a fairly significant restriction that wasn't there before

// The type argument must not be constant. For example, in C++,
// _Py_CAST(const PyObject*, expr) fails with a compiler error.

The PyUnicode_READ macro casts to a const pointer

#define PyUnicode_READ(kind, data, index) \
PyUnicode_READ(_Py_STATIC_CAST(int, kind), _Py_CAST(const void*, data), \
(index))

This is currently reported to be breaking Cython (cython/cython#4790).

I'd propose a fix which removes the const requirement:

template <typename T>
struct _Py_add_const {
    typedef const T type;
};
#  define _Py_CAST(tp, expr) \
       const_cast<tp>(reinterpret_cast<_Py_add_const<tp>::type>(expr))

on C++11 you could use the standard library std::add_cast instead, at the cost of an extra include. However it isn't available on c++03.

I realise this adds an extra struct _Py_add_const to the namespace. I'm not sure if that's desired, or how it should be named. If that's acceptable I'm happy to submit a PR for this.

@vstinner

Your environment

Current 3.11 branch