Consider the following code sample:
#include <iostream>
#include <string>
int main()
{
std::string str("someString"); // length 10
int num = -11;
std::cout << num % str.length() << std::endl;
}
Running this code on http://cpp.sh, I get 5
as a result, while I was expecting it to be -1
.
I know that this happens because the type of str.length()
is size_t
which is an implementation dependent unsigned, and because of the implicit type conversions that happen with binary operators that cause num
to be converted from a signed int
to an unsigned size_t
(more here);
this causes the negative value to become a positive one and messes up the result of the operation.
One could think of addressing the problem with an explicit cast to int
:
num % (int)str.length()
This might work but it's not guaranteed, for instance in the case of a string with length larger than the maximum value of int
. One could reduce the risk using a larger type, like long long
, but what if size_t
is unsigned long long
? Same problem.
How would you address this problem in a portable and robust way?