开发者

Reference-counting of std::string

I'm looking at the code for basic_string (that is bundled with g++ 4.2.1). The copy constructor makes use of a grab() function to "grab" a copy of a string (increment its r开发者_高级运维eference-count):

_CharT* _M_grab( const _Alloc& __alloc1, const _Alloc& __alloc2 ) {
  return (!_M_is_leaked() && __alloc1 == __alloc2) ? _M_refcopy() : _M_clone(__alloc1);
}

This increments the reference-count only if the allocators for the two strings are the same -- makes sense. However, the copy constructor is:

basic_string(const basic_string& __str)
: _M_dataplus(__str._M_rep()->_M_grab(_Alloc(__str.get_allocator()), __str.get_allocator()),
              __str.get_allocator())
{ }

The first allocator that's passed to _M_grab() is a copy of the second. Why? The only way that operator==() for allocator might return false is if the user is using a custom allocator. However, even if that's true, you'd think that a copied allocator would compare equal to its original, right? So:

  1. Why compare allocators at all?
  2. Why copy-construct an allocator and compare the copy to the original?
  3. What's a use-case where comparing a copy with its original would return false?

Update

Yes, _M_grab() is used in one other place: for assignment. In this case, the allocators passed to _M_grab() are different. Fine. But there still seems to be no reason to both copy-construct and then compare allocators in the constructor for string.


I know zip about the reasoning of the GCC team but here are my suppositions:

  1. For debugging? The allocators MUST be the same.

  2. So it can reuse _M_grab()?

  3. Should never happen?


  1. Allocators compare equal if objects allocated from one can be freed with the other. If that's the case, then two strings can share a reference to the same allocator; otherwise, each needs its own allocator.

  2. The comparison happens within _M_grab, which doesn't know that one argument has been copy-constructed from the other argument in this particular case. _M_grab is also called from assign, where the two strings may have different allocators.

  3. An allocator should always compare equal to a copy of itself.

Update

But there still seems to be no reason to both copy-construct and then compare allocators in the constructor for string.

Neither is there a particularly good reason to implement two almost-identical versions of _M_grab() to avoid the unnecessary comparison, which (for most allocators) will happen at compile time anyway. Maybe you think such a micro-optimisation would be desirable; apparently the author of this code didn't.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜