Boost logo

Boost :

From: Joe Gottman (joegottman_at_[hidden])
Date: 2001-06-05 21:04:43


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.

Joe Gottman


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