Boost logo

Boost :

From: Beman Dawes (bdawes_at_[hidden])
Date: 2001-06-06 11:47:46


At 10:04 PM 6/5/2001, Joe Gottman wrote:

>With the new versions of shared_ptr and shared_array, it is no longer
>necessary to guard against self-assignment. Here is the current version
of
>the share() method, which is used to implement assignment (I added the
>numbers to the left)
>
>void share(T* rpx, long* rpn) {
> if (pn != rpn) { // Q: why not px != rpx? A: fails when both == 0
>1) ++*rpn; // done before dispose() in case rpn transitively
> // dependent on *this (bug reported by Ken Johnson)
>2) dispose();
>3) px = rpx;
>4) pn = rpn;
> }
>
>
>Consider what would happen if the "if (pn != rpn) clause didn't appear
and
>pn were equal to rpn. In step 1), *rpn would be incremented by
1. Since
>*rpn was originally at least 1, after this step it would be at least 2.
>Then in step 2), dispose() would decrement *rp. Since (pn == rpn) and by
>the above *rpn is at least 2, after this step *pn is at least 1. Thus,
>dispose() will not delete pn and px, and step 1) followed by step 2)
>results
>in a no-op. Then step 3) and step 4) assign rpn to pn and rpx to px.
>Since
>they were equal to begin with, these are also no-ops. Thus, the
>self-assignment guards are not necessary. Their only effect is to speed
up
>the code in the case of self-assignments at the expense of slowing it
down
>in when there is no self-assignment. Since self-assignment is rare, the
if
>clause should be eliminated.

That seems correct to me. I'll add it for the next release, pending tests,
of course.

Thanks,

--Beman


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