'How to fix "error: call to 'abs' is ambiguous"

I'm running a simple C++ program from HackerRank about pointers and it works fine on the website. However, when I run it on MacOS, I get error: call to 'abs' is ambiguous and I'm not sure exactly what is ambiguous.

I've looked at other answers to similar issues, but the error message tends to be Ambiguous overload call to abs(double), which is not the issue I'm having, since I haven't used any doubles. I've also tried including the header files cmath and math.h, but the problem persists.

#include <stdio.h>
#include <cmath>

void update(int *a,int *b) {
    int num1 = *a;
    int num2 = *b;
    *a = num1 + num2;
    *b = abs(num1 - num2);
}

int main() {
    int a, b;
    int *pa = &a, *pb = &b;

    scanf("%d %d", &a, &b);
    update(pa, pb);
    printf("%d\n%d", a, b);

    return 0;
}

My issue occurs with line 8.



Solution 1:[1]

The full error message is:

$ clang++ test.cpp
test.cpp:8:10: error: call to 'abs' is ambiguous
    *b = abs(num1 - num2);
         ^~~
.../include/c++/v1/math.h:769:1: note: candidate function
abs(float __lcpp_x) _NOEXCEPT {return ::fabsf(__lcpp_x);}
^
.../include/c++/v1/math.h:769:1: note: candidate function
abs(double __lcpp_x) _NOEXCEPT {return ::fabs(__lcpp_x);}
^
.../include/c++/v1/math.h:769:1: note: candidate function
abs(long double __lcpp_x) _NOEXCEPT {return ::fabsl(__lcpp_x);}
^
1 error generated.

The three overloads of abs that you have from <cmath> are abs(float), abs(double) and abs(long double); it's ambiguous because you have an int argument and the compiler doesn't know which floating-point type to convert to.

abs(int) is defined in <cstdlib>, so #include <cstdlib> will resolve your problem.

If you're using Xcode, you can get more details about the error in the Issues navigator (?5) and clicking the triangle next to your issue.

Solution 2:[2]

For me, #include <cstdlib> didn't solve the issue, maybe because I didn't have to include anything to use abs. So, in case it helps someone else, with explicit casting, it worked well for me like in the next code:

*b = abs(int(num1 - num2));

Solution 3:[3]

if your using C compiler you should include

#include <stdlib.h>

and use abs without std::. If you use C++ compiler then you should change abs to std::abs.

Hope it helps:)

Solution 4:[4]

In templated code, it may be easily overlooked that std::abs is not defined for unsigned types. As an example, if the following method is instantiated for an unsigned type, the compiler may rightfully complain that std::abs is undefined:

template<typename T>
bool areClose(const T& left, const T& right) {
    // This is bad because for unsigned T, std::abs is undefined
    // and for integral T, we compare with a float instead of
    // comparing for equality:
    return (std::abs(left - right) < 1e-7);
}

int main() {
    uint32_t vLeft = 17;
    uint32_t vRight = 18;
    std::cout << "Are the values close? " << areClose(vLeft, vRight) << std::endl;
}

A better definition of areClose() in above code, that would coincidentally also solve the problem of std::abs() being undefined, could look like this:

template<typename T>
bool areClose(const T& left, const T& right) {
    // This is better: compare all integral values for equality:
    if constexpr (std::is_integral<T>::value) {
        return (left == right);
    } else {
        return (std::abs(left - right) < 1e-7);
    }
}

Solution 5:[5]

I used #include <bits/stdc++.h> as the only include statement and it worked for me. My code:

#include <bits/stdc++.h>  
using namespace std;
class Solution {
public:
    vector<int> findDuplicates(vector<int>& nums) {
        int n = nums.size();
        if(n == 0 || n == 1)
            return {};
        vector<int> ans;
        for(int i = 0; i < n; i++)
        {
            if(nums[abs(nums[i])-1] < 0)
                ans.push_back(abs(nums[i]));
            else
                nums[abs(nums[i])-1] = -1 * nums[abs(nums[i])-1];
        }
        return ans;
    }
};

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 ana
Solution 3 NewMe
Solution 4
Solution 5 Rajat Singh