thisptr considered harmful?

35 views
Skip to first unread message

Tom Swirly

unread,
Jun 14, 2016, 12:34:32 PM6/14/16
to cython-users
Sorry for all the traffic, but I'm doing my second Cython project so a lot of ideas are coming together.

It's very weird to see new() in use in modern C++ code - even if that C++ code is Cython.

I'm wondering why the thisptr idiom has continued to flourish, when it's so much easier to directly use C++ types as member elements in Cython classes?



Seems to work fine for me.  Is there some reason this is bad?  For example, I instrumented the destruction in the second link, and it seems to go off reliably just as expected.


--
     /t

http://radio.swirly.com - art music radio 24/7 366/1000

Ian Henriksen

unread,
Jun 14, 2016, 1:29:38 PM6/14/16
to cython-users, t...@swirly.com
I'm inclined to agree with you. For many common cases, storing the wrapped
object as a data member rather than a pointer is an unambiguously better approach.

That said, using the new and delete idioms in Cython's equivalent of constructors
and destructors isn't as harmful as raw new/delete use in other areas of the code
since it still ties resource lifetime to the existence of an object. In this case it's just a
Python object rather than a C++ one.

Best,
Ian Henriksen

Darsh Ranjan

unread,
Jun 14, 2016, 1:38:15 PM6/14/16
to cython...@googlegroups.com
On 06/14/2016 09:33 AM, Tom Swirly wrote:
> Sorry for all the traffic, but I'm doing my /second /Cython project so a
> lot of ideas are coming together.
>
> It's very weird to see new() in use in modern C++ code - even if that
> C++ code is Cython.
>
> I'm wondering why the thisptr idiom has continued to flourish, when it's
> so much easier to directly use C++ types as member elements in Cython
> classes?
>

I think the problem (or part of it) is that to declare a C++ class
instance directly as a member variable in a Cython class, it must have a
default constructor. On the other hand, the constructor of the C++ class
is supposed to fully initialize the instance, which often doesn't make
sense with no arguments. Therefore, even if you have complete control
over both the Cython class and C++ class, if you follow sound
programming practices, you can still end up in situations where you
can't directly declare an instance of the C++ class inside the Cython class.

>
> Examples here:
> https://github.com/rec/tada/blob/master/src/tada/signal/_combiner.pyx
> https://github.com/rec/tada/blob/master/src/tada/color/color_list.pyx#L25
>
> Seems to work fine for me. Is there some reason this is bad? For
> example, I instrumented the destruction in the second link, and it seems
> to go off reliably just as expected.
>

I didn't look into the Combiner example too much, but regarding
ColorVector: most container types can be empty, so that's a special case
where default constructors are pretty common and sensible.

>
> --
> /t
>
> http://radio.swirly.com - art music radio 24/7 366/1000
>
> --
>
> ---
> You received this message because you are subscribed to the Google
> Groups "cython-users" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to cython-users...@googlegroups.com
> <mailto:cython-users...@googlegroups.com>.
> For more options, visit https://groups.google.com/d/optout.

Robert Bradshaw

unread,
Jun 14, 2016, 1:41:29 PM6/14/16
to cython...@googlegroups.com
On Tue, Jun 14, 2016 at 10:29 AM, Ian Henriksen
<insertintere...@gmail.com> wrote:
> On Tuesday, June 14, 2016 at 10:34:32 AM UTC-6, Tom Swirly wrote:
>>
>> Sorry for all the traffic, but I'm doing my second Cython project so a lot
>> of ideas are coming together.
>>
>> It's very weird to see new() in use in modern C++ code - even if that C++
>> code is Cython.
>>
>> I'm wondering why the thisptr idiom has continued to flourish, when it's
>> so much easier to directly use C++ types as member elements in Cython
>> classes?
>>
>>
>> Examples here:
>> https://github.com/rec/tada/blob/master/src/tada/signal/_combiner.pyx
>> https://github.com/rec/tada/blob/master/src/tada/color/color_list.pyx#L25
>>
>> Seems to work fine for me. Is there some reason this is bad? For
>> example, I instrumented the destruction in the second link, and it seems to
>> go off reliably just as expected.
>>
>>
>> --
>> /t
>>
>> http://radio.swirly.com - art music radio 24/7 366/1000
>
>
> I'm inclined to agree with you. For many common cases, storing the wrapped
> object as a data member rather than a pointer is an unambiguously better
> approach.

The main reason thisptr is so common is because stack/member allocated
C++ objects didn't used to be supported (and they're still not
supported for objects without nullary constructors (different scoping
rules makes this messy...)).

> That said, using the new and delete idioms in Cython's equivalent of
> constructors
> and destructors isn't as harmful as raw new/delete use in other areas of the
> code
> since it still ties resource lifetime to the existence of an object. In this
> case it's just a
> Python object rather than a C++ one.

Yes, there is that advantage.

- Robert

Ian Henriksen

unread,
Jun 14, 2016, 1:49:09 PM6/14/16
to cython-users, darsh....@here.com
On Tuesday, June 14, 2016 at 11:38:15 AM UTC-6, Darsh Ranjan wrote:
On 06/14/2016 09:33 AM, Tom Swirly wrote:
> Sorry for all the traffic, but I'm doing my /second /Cython project so a
> lot of ideas are coming together.
>
> It's very weird to see new() in use in modern C++ code - even if that
> C++ code is Cython.
>
> I'm wondering why the thisptr idiom has continued to flourish, when it's
> so much easier to directly use C++ types as member elements in Cython
> classes?
>

I think the problem (or part of it) is that to declare a C++ class
instance directly as a member variable in a Cython class, it must have a
default constructor. On the other hand, the constructor of the C++ class
is supposed to fully initialize the instance, which often doesn't make
sense with no arguments. Therefore, even if you have complete control
over both the Cython class and C++ class, if you follow sound
programming practices, you can still end up in situations where you
can't directly declare an instance of the C++ class inside the Cython class.


Good point. Another situation that comes to mind is when you want methods
for your wrapper type to forward to virtual function calls. Storing a value of
the base class can result in data relevant to subclasses getting sliced away
when the data member is initialized. Avoiding object slicing is another
possible justification for the pointer redirect.

Best,
Ian Henriksen

Tom Swirly

unread,
Jun 14, 2016, 1:53:27 PM6/14/16
to cython-users
Summary:  It's common for historical reasons - and it's still useful for classes without a default constructor, and to fix the slicing problem.

Very clear!


--

---
You received this message because you are subscribed to the Google Groups "cython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cython-users...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.
Reply all
Reply to author
Forward
0 new messages