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("%dn%d", a, b);
return 0;
}
My issue occurs with line 8.
asked Jul 10, 2019 at 20:43
14
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.
answered Jul 10, 2019 at 20:47
zneakzneak
134k41 gold badges253 silver badges327 bronze badges
6
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));
answered Oct 17, 2020 at 15:19
anaana
1,0519 silver badges12 bronze badges
1
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);
}
}
answered Oct 25, 2021 at 20:13
emmenlauemmenlau
93811 silver badges18 bronze badges
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:)
answered Jul 10, 2019 at 20:56
NewMeNewMe
1624 bronze badges
4
Just put #include above the #include.The error will disappear.
answered Mar 29 at 11:38
1
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;
}
};
answered Jan 1, 2022 at 6:54
1
This is happening on Travis’s OS X machines. Full log is here. Details on XCode for this machine is here.
One odd thing is that c++11
should not be enabled and libc++
should not be being linked because -DOSXLIBSTD="libstdc++"
is being passed to cmake, but the configure output says:
-- Activating -std=c++11 flag for >= OS X 10.9
-- linking against libc++
[ 22%] Building CXX object CMakeFiles/OSRM.dir/Algorithms/DouglasPeucker.cpp.o
/Users/travis/build/DennisOSRM/node-osrm/Project-OSRM/Algorithms/DouglasPeucker.cpp:102:37: error:
call to 'abs' is ambiguous
const double distance = std::abs(temp_dist);
^~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/cmath:660:1: note:
candidate function
abs(float __x) _NOEXCEPT {return fabsf(__x);}
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/cmath:664:1: note:
candidate function
abs(double __x) _NOEXCEPT {return fabs(__x);}
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/c++/v1/cmath:668:1: note:
candidate function
abs(long double __x) _NOEXCEPT {return fabsl(__x);}
^
1 error generated.
make[2]: *** [CMakeFiles/OSRM.dir/Algorithms/DouglasPeucker.cpp.o] Error 1
lily19 0 / 0 / 0 Регистрация: 30.09.2016 Сообщений: 11 |
||||
1 |
||||
14.10.2016, 14:18. Показов 11826. Ответов 6 Метки нет (Все метки)
помогите пожалуйста, выдает ошибку. не знаю где
0 |
Programming Эксперт 94731 / 64177 / 26122 Регистрация: 12.04.2006 Сообщений: 116,782 |
14.10.2016, 14:18 |
6 |
7534 / 6396 / 2917 Регистрация: 14.04.2014 Сообщений: 27,863 |
|
14.10.2016, 14:53 |
2 |
Работает. Где ошибка?
0 |
lily19 0 / 0 / 0 Регистрация: 30.09.2016 Сообщений: 11 |
||||
14.10.2016, 14:57 [ТС] |
3 |
|||
я писала в dev и в онлайн компиляторе в c++shell. ошибка была показана тут:
0 |
0 / 0 / 0 Регистрация: 13.10.2016 Сообщений: 5 |
|
14.10.2016, 14:59 |
4 |
abs замени на fabs
0 |
lily19 0 / 0 / 0 Регистрация: 30.09.2016 Сообщений: 11 |
||||
14.10.2016, 19:48 [ТС] |
5 |
|||
мелочь, а важно..спасибо.мне помогло)) Добавлено через 4 часа 43 минуты
0 |
Падаван С++ 447 / 261 / 89 Регистрация: 11.11.2014 Сообщений: 916 |
|
14.10.2016, 19:59 |
6 |
z= D||E||F;
0 |
GbaLog- |
14.10.2016, 20:12
|
Не по теме:
я писала
я все сделал Кто же Вы? :scare:
0 |
Problem:
You are trying to compile a C/C++ program but you see an error message like
srcmain.cpp:127:21: error: call of overloaded 'abs(uint32_t)' is ambiguous
that refers to a line like
long timedelta = abs(millis() - startTime);
Solution:
Cast the argument to abs()
to int
or another suitable type:
long timedelta = abs(((int)millis() - startTime));
That should fix the error.
The reason for the error message is that millis()
and startTime
are both unsigned integers (uint32_t
), hence their difference (millis() - startTime
) is also an uint32_t
. However it makes no sense to compute the abs()
of an unsigned integer since the absolute value of an absolute-value integer is always the same as the input argument.
Then, the compiler tries to cast the uint32_t
to any type that is compatible with abs()
, like int
, float
, double
, … but it doesn’t know which of those types is the correct one to cast it to.
By saying call of overloaded abs()
the compiler is trying to tell you that there are multBiple argument types with which you can call abs()
, including int
, float
, double
, … – a function with the same name but different argument types is called overloaded.
By saying is ambiguous
, the compiler is telling you that it doesn’t know which of those variants of abs()
it should call.
Note that the compiler does not know that all overloaded variants of abs()
fundamentally do the same thing, so it won’t just cast your uint32_t
into any arbitrary type. Also, there are tiny details in how the abs()
variants work – for example, float abs(float)
will do a different calculation compared to double abs(double)
since it computes with 32-bit floating point numbers (float
) as opposed to 64-bit floating point numbers (double
).
Hence, the compiler can’t just assume that they are all the same and it doesn’t matter which one it calls, even though they represent the same underlying mathematical operation
Заголовок <math.h>
является заголовком C std lib. Он определяет много вещей в глобальном пространстве имен. Заголовок <cmath>
— это С++-версия этого заголовка. Он определяет по существу тот же самый материал в пространстве имен std
. (Есть некоторые отличия, например, версия С++ поставляется с перегрузками некоторых функций, но это не имеет значения.) Заголовок <cmath.h>
не существует.
Поскольку поставщики не хотят поддерживать две версии того, что по сути является одним и тем же заголовком, они придумали разные возможности, чтобы иметь только одну из них за кулисами. Часто, что заголовок C (поскольку компилятор С++ способен разобрать это, в то время как противоположное не будет работать), а заголовок С++ включает это и вытаскивает все в пространство имен std
. Или есть макрос магии для разбора одного и того же заголовка с или без namespace std
, обернутых вокруг него или нет. Для этого добавьте, что в некоторых средах это неудобно, если заголовки не имеют расширения файла (например, редакторы не могут выделить код и т.д.). Таким образом, некоторые поставщики имели бы <cmath>
как однострочный, включая другой заголовок с расширением .h
. Или некоторые из них будут отображать все, включая сопоставление <cblah>
с <blah.h>
(которое с помощью макроса становится заголовком С++, когда __cplusplus
определено и в противном случае становится заголовком C) или <cblah.h>
или что-то еще.
По этой причине на некоторых платформах, включая такие, как <cmath.h>
, которые не должны существовать, изначально удастся, хотя это может привести к тому, что компилятор не будет эффектно позже.
Я не знаю, какую версию std lib вы используете. Я предполагаю, что это тот, который поставляется с GCC, но этого я не знаю, поэтому я не могу точно объяснить, что произошло в вашем случае. Но это, безусловно, сочетание одного из вышеупомянутых хакеров, связанных с продавцом, и вы включаете заголовок, который вы не должны были включать в себя. Возможно, это тот, где <cmath>
отображается на <cmath.h>
с определенным (набором) макросов, которые вы не определили, так что вы оказались с обоими определениями.
Обратите внимание, что этот код еще не должен компилироваться:
#include <cmath>
double f(double d)
{
return abs(d);
}
В глобальном пространстве имен не должно быть abs()
(it std::abs()
). Однако в соответствии с описанными выше трюками реализации вполне может быть. Портирование такого кода позже (или просто попытка скомпилировать его с вашей следующей версией поставщика, что не позволяет этого) может быть очень утомительным, поэтому вам следует следить за этим.