I'm looking to eliminate special case in algorithm, and in order to do so I'd like to be sure that std::string::npos + 1
is 0
.
This is true in all the implementations I have tested, and searching in the standard I have 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
is defined as an unsigned integer type.
So, I suppose, my question boils down to whether (static_cast<T>(-1)) + 1
always gives 0
for unsigned integer type T?
No, adding one to the largest value of an unsigned integer type is not guaranteed to give you zero.
If size_type
is defined as unsigned short
, and int
is wider than unsigned short
, the LHS of your addition will be converted to the RHS, and you rely on the addition being performed in the LHS's type.
Worse yet, but this is far less likely to actually happen, if unsigned short
has exactly the same number of value bits as int
, the addition would overflow and result in undefined behaviour.
What you can do, however, is add 1U
, and convert the result of the addition back to T
. That should generate exactly the same code on common implementations, but would be guaranteed to be valid for all.