Neil Schemenauer
It looks like most (maybe all) of those warnings are triggered by Py_True and Py_False.
While it is the case that only those places trigger the warning, the issue goes beyond that. All usages of PyObject* in Python are incorrect, and may result in bad code.
Is there some other way of defining Py_True and Py_False so that we can avoid those errors?
We would have to give up PyObject_HEAD, and make that a structure.
Does this mean that code like:
void f (PyObject *a, PyDictObject *b) { a->ob_refcnt += 1; b->ob_refcnt -= 1; } [...] f((PyObject *)somedict, somedict);
is disallowed?
Correct. a->ob_refcnt += 1 has undefined behaviour, as 'a' does *not* point to a PyObject, but instead points to, say, a PyDictObject, and PyObject is not a field of PyDictObject. As a result of that, gcc can infer that 'a' and 'b' are different pointers, and it could implement that sequence as tmp1 = a->ob_refcnt; tmp2 = b->ob_refcnt; tmp1 += 1; tmp2 -= 1; a->ob_refcnt = tmp1; b->ob_refcnt = tmp2; The compiler could not use this optimization if we had struct _dictobject { PyObject _o; int ma_fill; int ma_used; int ma_mask; PyDictEntry *ma_table; PyDictEntry *(*ma_lookup)(PyDictObject *mp, PyObject *key, long hash); PyDictEntry ma_smalltable[PyDict_MINSIZE]; }; Then, of course, we'ld have to write b->_o->ob_refcnt -= 1; Regards, Martin