Ambiguous abs overload call (double)

I have the following C ++ code:

#include <math.h> #include <cmath.h> // per http://www.cplusplus.com/reference/clibrary/cmath/abs/ // snip ... if ( (loan_balance < 0) && (abs(loan_balance) > loan_payment) ) { ... } 

and make fires:

 error: call of overloaded 'abs(double)' is ambiguous 

also of interest:

 /usr/include/stdlib.h:785: note: candidates are: int abs(int) 

How can I indicate that the compiler should call abs () in cmath.h, which can handle float?

Information about the compiler (not sure if this is important):

 [some_man@some_box ~/some_code]# gcc -v Using built-in specs. Target: i386-redhat-linux Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr /share/info --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-libgcj-multifile --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre --with-cpu=generic --host=i386-redhat-linux Thread model: posix gcc version 4.1.2 20080704 (Red Hat 4.1.2-44) 
+56
c ++ std cmath
Sep 03 '09 at 15:13
source share
4 answers

The <math.h> header is the C std lib header. It defines many things in the global namespace. The <cmath> header is the C ++ version of this header. It defines essentially the same material in the std . (There are some differences, for example, the C ++ version comes with overloads of some functions, but this does not matter.) The header <cmath.h> does not exist.

Since suppliers do not want to support two versions of what is essentially the same headline, they came up with different possibilities to have only one of them behind the scenes. It is often that the C header (since the C ++ compiler is able to parse this, while the opposite will not work), and the C ++ header includes this and pulls everything into the std . Or there is a macro of magic to parse the same header with or without namespace std , wrapped around it or not. To do this, add that in some environments this is inconvenient if the headers do not have a file extension (for example, editors cannot select code, etc.). Thus, some providers would have <cmath> as single-line, including another header with the extension .h . Or some of them will display everything, including matching <cblah> with <blah.h> (which with the macro becomes the C ++ header when __cplusplus defined and otherwise becomes the C header) or <cblah.h> or <cblah.h> something else.

For this reason, on some platforms, including those such as <cmath.h> , which should not exist, it will succeed initially, although this may lead to the fact that the compiler will not be spectacular later.

I do not know which version of std lib you are using. I suppose this is the one that comes with GCC, but I don’t know this, so I can’t explain exactly what happened in your case. But this is certainly a combination of one of the aforementioned seller-related hackers, and you include a headline that you should not have included. Perhaps this is where <cmath> maps to <cmath.h> with a specific (set) of macros that you did not define, so you ended up with both definitions.

Note that this code should not compile yet:

 #include <cmath> double f(double d) { return abs(d); } 

The global namespace should not have abs() (it std::abs() ). However, in accordance with the tricks described above, there may well be implementations. Porting such code later (or just trying to compile it with your next version of the provider, which prevents this) can be very tedious, so you should keep track of this.

+47
Sep 03 '09 at 16:04
source share

It boils down to the following: math.h from C and was created over 10 years ago. In math.h, due to its primitive nature, the abs() function is essentially intended for integer types only, and if you want the absolute double value, you need to use fabs() . When C ++ was created, it took math.h and made it cmath . cmath is essentially math.h, but improved for C ++. He improved things like the need to distinguish between fabs() and abs, and just did abs() for both double and integer types. fabs() : Use math.h and use abs() for integers, fabs() for paired ones or use cmath and just abs for everything (easier and recommended)

Hope this helps anyone with the same problem!

+38
Mar 27 '11 at 16:26
source share

Use fabs () instead of abs (), it is the same, but for float instead of integers.

+17
Sep 14 '11 at 11:00
source share

In my cases, I solved this problem by using labs() instead of abs() .

0
Sep 22 '19 at 8:24
source share



All Articles