call of overloaded ‘abs(double&)’ is ambiguous - c++

we have following code in legacy and use this place hundread of place. I am compiling code with c++11 and got following error. I can understand issue(saw couple of question on stackoverflow) as abs support int/long int in C++11.
Is there any way to avoid 100 place and replace abs with fabs. Can I update such a way if it can handle both version. any input.
call of overloaded ‘abs(double&)’ is ambiguous
double abs(double d)
{
return (d < 0 ? -d : d);
}

Why redefine what is already defined?
You can find the function that you want in the header <cmath>.
Further reading on c++ reference.

#include <cmath>
add this header file and try to use abs() built-in function and see that work or not.

Related

constexpr math functions in C++20 [duplicate]

This question already has answers here:
Constexpr Math Functions
(3 answers)
Closed 2 years ago.
I am trying to do something like:
#include <cmath>
template <unsigned A, unsigned B>
struct fu {
constexpr unsigned long power_A_of_B = std::pow(A, B);
};
But the compiler gives error because pow() is not constexpr.
Why are math functions in header <cmath> not constexpr?
For example, log(), log2(), pow(), abs() and fmax() are not constexpr but others in <algorithm> are, such as max(), min() and `clamp()'.
Why are math functions in header not constexpr?
Reason is well hidden in documentation of std::pow:
std::pow, std::powf, std::powl - cppreference.com
Error handling
Errors are reported as specified in math_errhandling.
See documentation of math_errhandling.
Now how this macro could be handled in a constexpr?
So whole problem is maintaining compatibility with old specification.
The only possible solution is used alternative implementations. I've found something like this, didn't tested it, but looks promising. Found here.

A function call must have a constant value in a constant expression [duplicate]

This question already has an answer here:
Is it a conforming compiler extension to treat non-constexpr standard library functions as constexpr?
(1 answer)
Closed 4 years ago.
I have written a c++ program as blow:
#include <iostream>
int main()
{
constexpr double a = 4.0;
constexpr double b = sqrt(a);
std::cout << b << std::endl;
return 0;
}
When I tried to compile this code with visual studio 2017, I got an error that says a function call must have a constant value in a constant expression. The bad line is "constexpr double b = sqrt(a);".
But when I used g++ to compile the same code, no error was reported.
What's the reason of the error? What's the different between g++ and vc++?
sqrt isn't a constexpr function so can't be used in a constexpr expression. GCC seems to have a special built in version of sqrt which is constexpr. Clang doesn't allow this code either:
https://godbolt.org/z/SvFEAW
sqrt is required to be not a constant expression so constexpr double b = sqrt(a); is not supposed to work. Clang does not build this code as well. You also need to include <cmath> header in order to use this function.
include cmath library since you using a sqrt() function
http://www.cplusplus.com/reference/cmath/

Fixing odd compiler errors with std:: qualifier

I'm attempting to build source files of an open source C++ library written by someone else. This is being done on Windows with Cygwin's mingw-w64 compiler. The only compiler option I'm attaching is -std=gnu++11 since the library depends on some C++11 features.
Here are some examples of code in their library that appears to be causing issues:
CPScalar & Abs()
{
m_dValue = std::abs(m_dValue);
return *this;
}
//...
template<typename Unit>
bool SEScalarQuantity<Unit>::Set(const SEScalarQuantity<Unit>& s)
{
if (m_readOnly)
throw CommonDataModelException("Scalar is marked read-only");
if (!s.IsValid())
return false;
m_value = s.m_value;
m_isnan = (std::isnan(m_value)) ? true : false;
m_isinf = (std::isinf(m_value)) ? true : false;
m_unit = s.m_unit;
return true;
}
I get compiler errors on the std:: qualified functions above. The compiler error on the m_dValue = std::abs(m_dValue); line is
error: call of overloaded 'abs(double&)' is ambiguous
Which made me think it could be related to the question of whether std::abs(0u) is ill-formed as well as this answer to a similar SO question.
m_isnan = (std::isnan(m_value)) ? true : false; and the following line gives me
error: expected unqualified-id before '(' token
There are countless other uses of std:: that the compiler doesn't complain about. If I remove all of the std:: qualifiers in the statements that are giving me errors, the code compiles beautifully.
Thing is, this open source project is (presumably) being built by others without modification, so what am I missing here?
Add #include <cmath> to the file being compiled. The problem is that there are a couple of overloads of std::abs for integer types that are declared in the header <cstdlib> and the compiler is complaining that it doesn't know which of those to use. What's needed, though, is std::abs(double), and that's declared in <cmath>.
The reason that this code works with some compilers and not others is probably that there is a declaration of std::abs(double) coming in from some header other than <cmath>. That's allowed, but not required.

Function Overloading in Visual c++

I was writing a program of function overloading in Visual C++ 2010 .
Following is my code
// overload.cpp : Defines the entry point for the console application.
#include<Windows.h>
#include<iostream>
#include<conio.h>
using namespace std;
//abs is overloaded in 3 types
int abs(int i);
double abs(double d);
long abs(long f);
void main()
{
cout<<abs(-10)<<"\n";
cout<<abs(-11.0)<<"\n";
cout<<abs(-9L)<<"\n";
getch();
}
int abs(int i)
{
cout<<"using integer abs()\n";
return i>0? -i:i;
}
double abs(double d)
{
cout<<"using double abs()\n";
return d>0? -d:d;
}
long abs (long l)
{
cout<<"using long abs()\n";
return l>0?-l:l;
}
I am having problems in double abs and long abs function that
1>c:\users\abc\documents\visual studio 2010\projects\overload\overload\overload.cpp(22): error C2084: function 'double abs(double)' already has a body
1>c:\users\abc\documents\visual studio 2010\projects\overload\overload\overload.cpp(26): error C2084: function 'long abs(long)' already has a body
Why this problem is coming?
I have changed the compilation from c to c++
but recently I ran an other program for overloading,it worked.I don't know how? here is the code.
#include<iostream>
#include<cstdio>
#include<conio.h>
#include<cstring>
using namespace std;
void stradd(char*s1,char*s2);
void stradd(char*s1,int i);
void main()
{
char str[80];
strcpy(str,"hello");
stradd(str,"there");
cout<<str<<"\n";
getch();
}
//concatenate a string with a "stringized "integer
void stradd(char*s1,int i)
{
char temp[80];
sprintf(temp,"%d",i);
strcat(s1,temp);
}
//concatenate 2 strings
void stradd(char*s1,char *s2)
{
strcat(s1,s2);
}
and output is hellothere
Your problem comes from a header in which abs is declared for some types such as double. You're not allowed to have to functions with exactly the same header (that is, same return type, same name, same list of parameters, same qualifiers such as const).
There are two ways of avoiding this:
Use the standard library: std::abs is good, you don't need to implement it yourself
Naming the method absoluteValue or myAbs or whatever you like, but not abs
A third way, namely removing using namespace std does not work according to your comment. This is because you include Windows.h. This itself includes a bunch of headers, probably including math.h. This gives a method called abs in the global namespace. Better don't include Windows.h and include cmath if you need to. Then, abs is only declared in namespace std, hence you can call it with std::abs and is different from abs.
When overload resolution cannot select one function as the unique best match, the call is ambiguous. An ambiguous call produces a compilation error.
In std there is already an abs() with the following signature:
int abs (int n);
So while you try to overload it with double and long it results in ambiguity for the compiler.
If you're a beginner learning about coding i suggest you to use function names not defined in libraries (at least the ones you have included).
stefan have already given the solution to it:
Remove using namespace std; and explicitly write std::cout
OR
Re name your function to absoluteValue or something else
OR
Use explicit namespaces in function declaration and calls. (Not tested, though it should work)
Put your function inside a class or namespace.
Maybe this would provide you with a little insight (From SO).
EDIT:
The second question's overloaded functions stradd() is not defined in any other library. That is why no Compilation Errors. The following function signature in your code will result an error: char * strcat ( char * destination, const char * source )
Your primary problem is that you use global namespace. Just declare your function in your own namespace and all name collisions will be gone.
Let me explain why you're getting those compile-time errors.
Somewhere in the headers you included there are double abs(double) and long abs(long) functions. Then you're creating functions with the same signatures by your own. So compiler just don't know what to use when you'll call one of them - there are 2 pairs of equal functions. So it refuses to compile that, and you're getting those errors.
So you have 2 choices - hope that every time you'll want to create a function you will choose an unique name, or just create a namespace and your function names should be unique only to another functions in your namespace.
And it's not about overloading - void func(int i) overloads void func(float f), but void func(int i) overrides void func(int i). You can override superclass member functions in subclasses, but you cannot override standalone functions like abs().
just change abs function name with another.
abs() is a keyword therefore it is showing errors.

cmath functions generating compiler error

I've written a small program that utilizes the Fast Light Toolkit and for some reason a compiler error is generated when trying to access the functions in the cmath header.
Such as error ::acos has not been declared.
This goes on for pretty much every function it tries to use in the header. What could I be missing?
The header files I have included are
Simple_window.h
Graph.h
both of which are part of the FLTK.
The code is this:
#include "Simple_window.h" // get access to our windows library
#include "Graph.h" // get access to graphics library facilities
int main()
{
using namespace Graph_lib; // our graphics facilities are in Graph_lib
Point tl(100,100); // to become top left corner of window
Simple_window win(tl,600,400,"Canvas"); // make a simple window
Polygon poly; // make a shape (a polygon)
poly.add(Point(300,200)); // add a point
poly.add(Point(350,100)); // add another point
poly.add(Point(400,200)); // add a third point
poly.set_color(Color::red); // adjust properties of poly
win.attach(poly); // connect poly to the window
win.wait_for_button(); // give control to display engine
}
Edit: Here is example code of when the compiler error is generated. This is inside the cmath header.
namespace std
{
// Forward declaration of a helper function. This really should be
// an `exported' forward declaration.
template<typename _Tp> _Tp __cmath_power(_Tp, unsigned int);
inline double
abs(double __x)
{ return __builtin_fabs(__x); }
inline float
abs(float __x)
{ return __builtin_fabsf(__x); }
inline long double
abs(long double __x)
{ return __builtin_fabsl(__x); }
using ::acos; //ERROR HERE
inline float
acos(float __x)
{ return __builtin_acosf(__x); }
inline long double
acos(long double __x)
{ return __builtin_acosl(__x); }
template<typename _Tp>
inline typename __enable_if<double, __is_integer<_Tp>::_M_type>::_M_type
acos(_Tp __x)
{
return __builtin_acos(__x);
}
Edit: Code::blocks is saving files as C files....
When you include the C++ version (<cXXXX>) of standard C libraries all the symbols are defined within the std namespace. In C++ you do not need to link against the math library (-lm is not required)
#include <cmath>
#include <iostream>
int main()
{
std::cout << std::fabs( -10.5 ) << std::endl;
}
I had this problem - it was driving me crazy but I tracked down the cause, and it was a little different than what I've seen reported on this issue.
In this case, the general cmath header (or math.h - the error and solution occur in C++ or C) had architectural environment switches to include architecture specific math subheaders. The architecture switch (environment variable) hadn't been defined, so it was punting and not actually including the headers that truly defined the math functions.
So there was indeed a single math.h or cmath.h, and it was included, but that wasn't enough to get the math functions. In my case, rather than define the architectural variable, I instead found the location of the correct sub math headers and added them to my compile path. Then the project worked!
This seems to be an issue that comes up a lot when porting Linux projects to OS-X. I'd imagine it might occur anytime a project was moved betwee platforms such that the standard library headers are arranged differently.
Jeff
Since your code as shown above does not directly call acos(), there is arguably a bug in one of the headers that you do use. It appears there is some (inline) code in one of the headers that invokes the acos() function without ensuring that the function is properly declared. This might be a macro or an inline function.
The best fix is to ensure that the headers are self-contained - change the headers.
If that is not possible, the hackaround is to include the appropriate header (#include <cmath>, probably) in the source code.
The program is able to access the cmath header, the error is in the cmath header itself.
In that case, you will probably need to provide a global acos() function (declaration at least, possibly definition too) that calls onto std::acos():
double acos(double x) { return std::acos(x); }
Just make sure this is not inside any namespace - not even the anonymous one. (Check compiled with G++ 4.0.1 on MacOS X, with '#include <cmath>' preceding it. Given that you have a problematic <cmath> header, you might need to get fancy:
extern double std::acos(double);
double acos(double x) { return std::acos(x); }
#include <cmath>
This is pretty nasty - are you sure there isn't a bug-fixed version of your compiler?
Is there any chance that you've got '#include <cmath>' inside a namespace?
It also happens in Visual C++, in programs that do not sapuse to use cmath.
I found that the problem is that I used main.c file instead of main.cpp file.
The error is most likely to be in your code and not in cmath... unless you changed something in cmath. Could you copy the errors and tell us what is the application you are using to program?