Why does shared_ptr<T>::use_count() return a long instead of an unsigned type?

别来无恙 提交于 2021-02-15 12:07:38

问题


shared_ptr observers 20.8.2.2.5 C++14 Final Draft (n4296)

   long use_count() const noexcept;

Returns: the number of shared_ptr objects, *this included, that share ownership with *this, or 0 when *this is empty.

[Note: use_count() is not necessarily efficient. — end note]


回答1:


According to this page

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2003/n1450.html

The return type of use_count is signed to avoid pitfalls such as p.use_count() > -1 evaluating to false.

with a reference to

John Lakos, Large-Scale C++ Software Design, section 9.2.2, page 637, Addison-Wesley, July 1996, ISBN 0-201-63362-0.

Basically, it looks like a nanny-grade decision, tailored for freshman year software developers.




回答2:


The reason is that the most appropriate type for a counter of this kind is a regular signed integer, even if this counter is never going to get below 0.

Why a counter should be unsigned? The fact that it cannot become negative is not a valid excuse at all given current real meaning of unsigned for the language.

unsigned for C++ doesn't mean an "integer number that cannot be negative". To understand why this definition simply doesn't make sense consider that

  • The difference of two unsigned is unsigned
  • The addition of an unsigned with a signed is unsigned
  • An unsigned value is never bigger than -1

None of the above makes any sense if you consider unsigned to mean "non-negative".

Using unsigned for size_t was a mistake (see for example Why is size_t unsigned?), only partially* excusable because in the 16-bit era one extra bit was considered worth the wrong semantics that unsigned types have in C++ for this kind of use.

Unfortunately now the size_t mistake cannot be fixed (because of backward compatibility) but why repeating the same mistake in another unrelated area?

Please note that probably the big mistake made was just the choice of the name unsigned (given its real meaning). If that type would have been named (more appropriately) modulo then probably it would be more evident why using a modulo int for the size of a string doesn't make any sense at all.

The name is irrelevant, what it counts is the semantic and unsigned simply has the wrong semantic for a counter or a size.

(*) I personally don't think it was a good enough reason even back then. If 32767 is not enough for a size now, then 65535 won't be enough really soon. Just a single bit (twice the value) was not, in my opinion, an acceptable price for such a bending of the semantic.

EDIT

I've published a video in which I'm discussing in more details why I think that using and unsigned type for size_t was a design mistake in C++.

Slides can be downloaded from http://raksy.dyndns.org/unsigned.pdf



来源:https://stackoverflow.com/questions/36370180/why-does-shared-ptrtuse-count-return-a-long-instead-of-an-unsigned-type

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!