Reputation: 8759
I'm getting warning for signed vs. unsigned comparison when I'm comparing a std::abs(int)
against an unsigned
. And indeed, std::abs
returns signed values. Why was that choice made? It would have solved the problem of negative values whose absolute value cannot be represented in the signed type.
And then, is there something cleaner (i.e., without cast) than this to avoid warnings?
#include <cassert>
#include <cstdlib>
// max(1, lhs + rhs). (lhs must be > 0)
unsigned add(unsigned lhs, int rhs)
{
return
(0 < rhs || static_cast<unsigned>(-rhs) < lhs
? rhs + lhs
: 1);
}
int main()
{
assert(add(42, -41) == 1);
assert(add(42, 0) == 43);
assert(add(42, 1) == 43);
assert(add(42, -51) == 1);
}
Upvotes: 17
Views: 3380
Reputation: 799
In c++11 you could write your own to make to cast automatic:
#include <utility>
template< typename T >
typename std::make_unsigned<T>::type abs( T x )
{
//We need to cast before negating x to avoid the overflow.
return x < 0? -static_cast<std::make_unsigned<T>::type>(x) : x;
}
I tried it with -Wall options, got no warnings.
Upvotes: 4
Reputation: 45
That is no choice, that is definition. abs is implemented via a template, which returns the type in which the original value was stored. The result will always be valid, as the absolute value of an signed integer will always fit in its original data type. An explicit cast to your target data type should be enough to get rid of any warnings...
Upvotes: 0
Reputation: 5126
The short answer is that this is done so that the return type of abs
is the same as its input type. This is exactly what you want, most of the time.
Mostly, when calling abs, you're dealing with an equation where all elements are of the same type (or you'd get warnings) and you want to use the magnitude of some variable in that equation. That doesn't mean you want to change the type of one of the variables in your equation. That would give the kind of issues/warnings you're mentioning.
So, in short, it is more common and more natural to want the same input and output type when asking for the absolute value of a signed variable. The magnitude of value isn't commonly used as an index.
Upvotes: 10