Search code examples
c++stringstlsize-tsize-type

How can size_type be an unsigned integral if npos is -1?


If the std::size_type of a std::string is that of the default allocator,

21.3.1 Class template basic_string
typedef typename allocator_traits<Allocator>::size_type size_type;

And the std::size_type for the default allocator is that of std::size_t,

20.9.9 The default allocator
typedef size_t size_type;

And we know that std::size_t is always an unsigned integer type,

C++ Standard
5.3.3 Sizeof
The result of sizeof and sizeof... is a constant of type std::size_t.
[ Note: std::size_t is defined in the standard header <cstddef>

8.2 Types
The contents are the same as the Standard C library header <stddef.h>, with the following changes:


C Standard
6.5.3.4 The sizeof and _Alignof operators
The value of the result of both operators is implementation-defined,
and its type (an unsigned integer type) is size_t, defined in <stddef.h> (and other headers).

How can std::basic_string::npos (defined as a size_type) be -1?


Solution

  • The C++ spec requires that signed types can be converted to unsigned types. §4.7/2 states that

    If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source integer (modulo 2n where n is the number of bits used to represent the unsigned type)

    This means that the C++ spec guarantees that -1 can be converted to a size_type even if size_type is unsigned, and the result will be equal to the largest possible size_type because adding 1 to that number needs to give back 0.