Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork33.3k
Description
When I convertedPy_REFCNT(),Py_TYPE() andPy_SIZE() macros to static inline functions (issue#83754), I choseconst PyObject* for their argument because these macros don't modify any member of the PyObject structure. When the Py_IS_TYPE() function was added, it followed the trend (commit8767ce9). The_PyObject_CAST_CONST() macro was added to easily convert any pointer toconst PyObject* for these macros expectingconst PyObject*.
The problem is that passingPyObject* to one of these functions emits a compiler warning usinggcc -Wcast-qual. The_PyObject_CAST_CONST() doesn't make the warning quiet.
Example explaining the issue:
staticinlineintvalue(int*p) {return*p; }#definevalue(p) value((int*)(p))intmain(){intx=1;constint*p=&x;returnvalue(p);}
Output:
$ gcc x.c -Wcast-qual -o x&& ./x;echo$?x.c: Infunction'main':x.c:2:24: warning: cast discards'const' qualifier from pointer targettype [-Wcast-qual] 2|#define value(p) value((int*)(p))| ^x.c:8:12: note:in expansion of macro'value' 8|return value(p);| ^~~~~1
In practice, the problem was that building a C extension (which includes<Python.h>) withgcc -Wcast-qual -Werror on Python 3.10 failed with an error on Py_IS_TYPE() implemented as:
staticinlineintPy_IS_TYPE(constPyObject*ob,constPyTypeObject*type) {returnPy_TYPE(ob)==type;}#definePy_IS_TYPE(ob,type) Py_IS_TYPE(_PyObject_CAST_CONST(ob), type)
See the issue#88544 for the compiler error. I removed the Py_TYPE() call in Py_IS_TYPE() to work around the issue:
staticinlineintPy_IS_TYPE(constPyObject*ob,constPyTypeObject*type) {// bpo-44378: Don't use Py_TYPE() since Py_TYPE() requires a non-const// object.returnob->ob_type==type;}#definePy_IS_TYPE(ob,type) Py_IS_TYPE(_PyObject_CAST_CONST(ob), type)
But this problem strikes back when I try to convert unicodeobject.h macros to static inline functions for PEP 670 which removes the cast toPyObject* in the limited C API version 3.11: see PR#91696 and PR#91705. For example, _Py_strhex_with_sep() and _Py_strhex_bytes_with_sep() function get aconst PyObject* argument and use PyUnicode C functions like PyUnicode_READY(), PyUnicode_KIND() and PyUnicode_READ_CHAR(), but these PyUnicode functions expectPyObject*: theconst qualifier is lost. If Python/pystrhex.c is built withgcc -Wcast-qual, gcc emits warnings on PyUnicode_KIND() and PyUnicode_READ_CHAR() calls. That's just an example of problem which can happen in C extensions as well.
To avoid these problems, I propose to avoidconst PyObject* in Python: only usePyObject*.