Boost logo

Boost :

From: Peter Dimov (pdimov_at_[hidden])
Date: 2003-09-11 10:27:33


Richard Hadsell wrote:
> Daniel Frey wrote:
>
>> ...
>> if (ptr.get()) ...
>> if (ptr) ... // Less efficient.
>> ...
>> As I think that efficiency is more important than a nice error
>> message, I'd like to propose changing shared_ptr's code appropriately
>> to avoid the overhead imposed by the current safe-bool-idiom.
>> Comments?

The two 'almost bool' idioms are not equivalent. Providing a single
conversion to "unspecified bool type" allows for example code like:

void f(bool);
void f(int);

f(p);

to compile. I'm not sure yet whether this is a good thing or not. I think
that at one point I convinced myself that it is good, but I can't remember
the details. I tend to favor the 'single conversion to unspecified boolean
type' approach from a specification point of view, too.

> I was interested in this thread, because I use scoped_ptr and
> scoped_array extensively, and performance is important for my
> application. I was glad to see the bool operator added to those
> classes, and I laboriously changed all my 'if (ptr.get())'s to 'if
> (ptr)', not realizing the compiler might not generate code as
> efficient.
>
> Is it true that the discussion applies to the scoped_ classes as well
> as shared_ptr? And is someone willing to fix them, too?

I think that the actual difference is small to nonexistent, but if this
issue is considered important, we can switch from a member function pointer
to a data member pointer as the unspecified bool type. It is as efficient as
a plain operator bool, at least on the compiler I tried:

operator T * this_type::*unspecified_bool_type() const:

    mov eax, DWORD PTR _pv$[esp-4]
    mov ecx, DWORD PTR [eax]
    neg ecx
    sbb ecx, ecx
    test ecx, OFFSET FLAT:?get@?$shared_ptr_at_X@boost@@QBEPAXXZ ;
boost::shared_ptr<void>::get
    je SHORT $L5261

operator bool:

    mov eax, DWORD PTR _pv$[esp-4]
    cmp DWORD PTR [eax], 0
    je SHORT $L5240

operator T * this_type::*unspecified_bool_type:

    mov eax, DWORD PTR _pv$[esp-4]
    cmp DWORD PTR [eax], 0
    je SHORT $L5261

All code for

    if(pv)

This improvement has been first suggested by Daveed Vandevoorde. I haven't
applied it to the smart pointers since "if it's not broken don't fix it" but
perhaps the time has come to do so.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk