Is the C ++ standard guaranteed that std :: basic_string :: npos + 1 == 0?

I'm looking to exclude a special case in an algorithm, and for that I would like to be sure there std::string::npos + 1

is 0

.

This is true in all the implementations I've tested, and looking in the standard I found the following:

namespace std {
  template<class charT, class traits = char_traits<charT>,
    class Allocator = allocator<charT> >
  class basic_string {
    // ...
    typedef typename allocator_traits<Allocator>::size_type size_type;
    // ...
    static const size_type npos = -1;
    ...
  };
}

      

allocator_traits<Allocator>::size_type

defined as an unsigned integer type.

So I suppose my question boils down to what (static_cast<T>(-1)) + 1

always gives 0

for an unsigned integer type T?

+3


source to share


1 answer


No, adding one to the largest unsigned integer value does not guarantee that you get zero.

If size_type

defined as unsigned short

, or int

wider than unsigned short

, the LHS of your append will be converted to RHS and you will rely on the append being done in the LHS type.



Worse, but much less likely to happen if it unsigned short

has exactly the same number of bits of value as int

, the addition will overflow and result in undefined behavior.

However, you can add 1U

and convert the add result back to T

. This should generate exactly the same code for common implementations, but is guaranteed to be valid for everyone.

+5


source







All Articles