Hello, The following is use by the boost shared_ptr assignment operators (see boost\smart_ptr.hpp)... void share(T* rpx, long* rpn) { if (pn != rpn) { // Q: why not px != rpx? A: fails when both == 0 ++*rpn; // done before dispose() in case rpn transitively // dependent on *this (bug reported by Ken Johnson) dispose(); px = rpx; pn = rpn; } } // share ...I curious to know what it means by "fails when both == 0". I mean, I can't see as the sky would fall in if the test was "if (px != rpx)". Am I missing something? Thanks, Louis.
From: "Louis Lavery"
Hello,
The following is use by the boost shared_ptr assignment operators (see boost\smart_ptr.hpp)...
void share(T* rpx, long* rpn) { if (pn != rpn) { // Q: why not px != rpx? A: fails when both == 0 ++*rpn; // done before dispose() in case rpn transitively // dependent on *this (bug reported by Ken Johnson) dispose(); px = rpx; pn = rpn; } } // share
...I curious to know what it means by "fails when both == 0".
It's possible that px == rpx == 0, yet pn != rpn. -- Peter Dimov Multi Media Ltd.
----- Original Message -----
From: Peter Dimov
From: "Louis Lavery"
Hello,
The following is use by the boost shared_ptr assignment operators (see boost\smart_ptr.hpp)...
void share(T* rpx, long* rpn) { if (pn != rpn) { // Q: why not px != rpx? A: fails when both == 0 ++*rpn; // done before dispose() in case rpn transitively // dependent on *this (bug reported by Ken Johnson) dispose(); px = rpx; pn = rpn; } } // share
...I curious to know what it means by "fails when both == 0".
It's possible that px == rpx == 0, yet pn != rpn.
-- Peter Dimov Multi Media Ltd.
Hello, Yes, I see that, but I can't see what's wrong with using the test "if ( px != rpx )". Or, to put it another way, if px == rpx == 0 who cares whether pn equals rpn or not? Louis.
On 12/14/01 1:40 PM, "Louis Lavery"
Yes, I see that, but I can't see what's wrong with using the test "if ( px != rpx )".
Or, to put it another way, if px == rpx == 0 who cares whether pn equals rpn or not?
If both px and rpx are 0, but pn and rpn are the same, then the dispose() will cause the single object pointed to by pn to be deleted. Then pn will point to freed memory. And dereferencing pn will result in undefined behavior. And destroying the shared_ptr will result in undefined behavior because it will try to delete the same thing again. -- Darin
On 12/14/01 1:40 PM, "Louis Lavery"
Yes, I see that, but I can't see what's wrong with using the test "if ( px != rpx )".
Or, to put it another way, if px == rpx == 0 who cares whether pn equals rpn or not?
Oops, my last message was a mistake. I don't know the answer. -- Darin
----- Original Message -----
From: Darin Adler
On 12/14/01 1:40 PM, "Louis Lavery"
wrote: Yes, I see that, but I can't see what's wrong with using the test "if ( px != rpx )".
Or, to put it another way, if px == rpx == 0 who cares whether pn equals rpn or not?
Oops, my last message was a mistake. I don't know the answer.
-- Darin
Well, it almost convinced me until I read it a few times. I've been pondering it some more and am now sure there's nothing wrong with "if (px != rpx)" and, this being the case, is to be prefered over "if (pn != rpn)". Why? Because the later is confusing, witness this thread ;-) Thanks for your reply, Louis.
From: "Louis Lavery"
From: Peter Dimov
From: "Louis Lavery"
void share(T* rpx, long* rpn) { if (pn != rpn) { // Q: why not px != rpx? A: fails when both ==
0
++*rpn; // done before dispose() in case rpn transitively // dependent on *this (bug reported by Ken Johnson) dispose(); px = rpx; pn = rpn; } } // share
...I curious to know what it means by "fails when both == 0".
It's possible that px == rpx == 0, yet pn != rpn.
Yes, I see that, but I can't see what's wrong with using the test "if ( px != rpx )".
Or, to put it another way, if px == rpx == 0 who cares whether pn equals rpn or not?
Two shared_ptr's are either copies of each other (pn == rpn) or they are not (pn != rpn). It is possible for two shared_ptr's to be both zero, yet to have different counts: shared_ptr<int> a; shared_ptr<int> b; // b.use_count() == 1 b = a; // b.use_count() == 2 It's also possible to have two NULL shared_ptr's that have the same count: shared_ptr<int> a; shared_ptr<int> b(a); // b.use_count() == 2 b = a; // b.use_count() == 2 If you change the test to px != rpx, the first example will leave b with the same count. This is not correct since after the assignment a and b are guaranteed to share the same count (and hence use_count() must be at least 2.) I realize that this is a bit confusing; think about it this way. The test is an "optimization." The results of share() must be the same even without the test. -- Peter Dimov Multi Media Ltd.
----- Original Message -----
From: Peter Dimov
From: "Louis Lavery"
From: Peter Dimov
From: "Louis Lavery"
an "optimization." The results of share() must be the same even without
[snip] the
test.
-- Peter Dimov Multi Media Ltd.
Ah! Right, so part of boost/shared_ptr's definition is that after assinging b to a, a.px == b.px *and* a.pn == b.pn. Thanks for the clarification, Louis.
participants (3)
-
Darin Adler
-
Louis Lavery
-
Peter Dimov