Trevor Hickey
Trevor Hickey

Reputation: 37914

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?

Upvotes: 0

Views: 278

Answers (2)

templatetypedef
templatetypedef

Reputation: 373082

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.

Upvotes: 4

juanchopanza
juanchopanza

Reputation: 227538

The definition uses the fact that unsigned integers follow modular arithmetic, and -1 converts to the largest unsigned integer of a given type.

Upvotes: 2

Related Questions