Reputation: 1410
I am trying to compile the following code:
#include <stdlib.h>
static
unsigned iSqr( unsigned i )
{
unsigned res1 = 2;
unsigned res2 = i/res1;
while( abs( res1 - res2 ) > 1 )
{
res1 = (res1 + res2)/2;
res2 = i/res1;
}
return res1 < res2 ? res1 : res2;
}
using g++ test.cc -o test
.
However, g++ compiler fails with the following error:
test.cc: In function 'unsigned int iSqr(unsigned int)':
test.cc:8:29: error: call of overloaded 'abs(unsigned int)' is ambiguous
while( abs( res1 - res2 ) > 1 )
^
In file included from /usr/include/c++/6/cstdlib:75:0,
from /usr/include/c++/6/stdlib.h:36,
from test.cc:2:
/usr/include/stdlib.h:735:12: note: candidate: int abs(int)
extern int abs (int __x) __THROW __attribute__ ((__const__)) __wur;
^~~
In file included from /usr/include/c++/6/stdlib.h:36:0,
from test.cc:2:
/usr/include/c++/6/cstdlib:185:3: note: candidate: __int128 std::abs(__int128)
abs(__GLIBCXX_TYPE_INT_N_0 __x) { return __x >= 0 ? __x : -__x; }
^~~
/usr/include/c++/6/cstdlib:180:3: note: candidate: long long int std::abs(long long int)
abs(long long __x) { return __builtin_llabs (__x); }
^~~
/usr/include/c++/6/cstdlib:172:3: note: candidate: long int std::abs(long int)
abs(long __i) { return __builtin_labs(__i); }
^~~
Why this error is happening and how to fix it?
g++ version is: gcc version 6.3.0
Upvotes: 3
Views: 17148
Reputation: 5270
abs
in <stdlib.h>
(since c++11): http://www.cplusplus.com/reference/cstdlib/abs/
int abs ( int n);
long int abs ( long int n);
long long int abs (long long int n);
The call will be ambiguous if overload resolution cannot select a match to the call that is uniquely better than such undifferentiable functions.
You can cast the argument explicitly like:
static_cast<int>(res1 - res2)
Upvotes: 6
Reputation: 743
Edit: <cstdlib>
should handle the overloads (and should be preferred anyways), see the question here
Note that there are some logic errors here. First of all, what you are doing is probably not what you want. res1 - res2
is arithmetic between two unsigned
types, and so the result is also going to be unsigned
. If you go below 0, you wrap back to max int. abs()
is pointless here, that value will never be negative because the type disallows it. Even with the header that compiles this code, the compiler will still warn about this.
I highly recommend you stick to signed integers when dealing with arithmetic to avoid these pitfalls, and if you really need the storage, use 64-bit integers.
So my real answer would be, switch unsigned
to int
Also note: unsigned res2 = i / res1;
res2 will be truncated towards 0 here, I'm not sure if that is what you want or not.
Upvotes: 4
Reputation: 406
You can just cast the result to a signed datatype for abs to know which one you're calling like this:
while( abs( int(res1 - res2) ) > 1 )
but rethink again of what you need to do here as the result of minus operation on unsigned is still unsigned, so if the result goes below 0 it will turn to be a great number (as a normal overflow), so I think the use of signed variables is the best way to solve the issue in the first place
int iSqr( unsigned i )
{
int res1 = 2;
int res2 = i/res1;
while( abs(res1 - res2) > 1 )
{
res1 = (res1 + res2)/2;
res2 = i/res1;
}
return res1 < res2 ? res1 : res2;
}
Upvotes: 5