[Pyrex] Missing Py_DECREF in generated code

Igor Khavkine igor.kh at gmail.com
Fri Dec 1 00:40:33 UTC 2006


On 11/30/06, Greg Ewing <greg.ewing at canterbury.ac.nz> wrote:
> Igor Khavkine wrote:
>
> > cdef void leak (void *obj):
> >       cdef T t
> >       (<T> obj).j = 1
> >       (<T> obj).i = (<T> obj).i + 1
> >       (<T> obj).a[0] = (<T> obj).a[0] + 1   # <-- Missing Py_DECREF
> >       t = <T> obj
> >       t.a[0] = t.a[0] + 1
>
> Is there any reason you couldn't write this as
>
>    cdef void leak (T obj):
>      obj.j = 1
>      obj.i = obj.i + 1
>      obj.a[0] = obj.a[0] + 1

The only reason (albeit not an insurmountable one) is that leak()
would be called from C code and have its argument as an opaque object
handle (void *).

> If you really must use a typecast, it's safest to just
> do one of them and put the result into an appropriately
> typed local as soon as possible, e.g.
>
>    cdef void leak (void *obj):
>      cdef T t
>      t = <T>obj
>      t.j = 1
>      t.i = t.i + 1
>      t.a[0] = t.a[0] + 1

That's the solution that I've already adopted. And I've already
checked that the code generated from the last two lines of my example
is correct.

> The reference counting behaviour of typecasts involving
> object references is not well defined, and you do it at
> your own risk.

That's somewhat misleading. Each line in my example, except the
indicated one, produces correct code. I think anyone, who's seen that
the first two assignments in leak() work properly, would expect the
third one to work as well. That's why it's a bug.

Igor



More information about the Pyrex mailing list