I'm getting a lot of headache with a simple isnan test in my code. I have a 3d vector class with variables x,y,z of type double, and the following function in the header file:
#ifdef WIN32
bool IsValid() const {return !_isnan(x) && _finite(x) && !_isnan(y) && _finite(y) && !_isnan(z) && _finite(z);} //is a valid vector? (funky windows _ versions...)
#else
bool IsValid() const {return !isnan(x) && finite(x) && !isnan(y) && finite(y) && !isnan(z) && finite(z);} //is a valid vector?
#endif
I'm building in a Linux GCC environment on Eclipse CDT and getting the following error:
Function '__isnanl' could not be resolved
as well as
Function '__isnanf' could not be resolved
for all instances of isnan. Using std::isnan and including float.h and math.h don't solve it. Does anyone know what's going on?
1) Try to include <math.h>
2) Write your own isnan(x) function
bool isnan(x)
{
if (x==x)
{
return false;
}
else
{
return true;
}
}
3) Could it be a silly naming problem?isnanl should probably be defined as isnan?
See: Checking if a double (or float) is NaN in C++
I run into the same issue. isnan() works on command-line but annoyingly, Eclipse reports it as an error. The problem is due to Eclipse CDT using the gcc compiler little differently. Looking a bit deeper, isnan() seems to be a macro that is translated to __isnan() or some other functions depending on some flags. Maybe these flags differ when you compile from Eclipse.
I fixed it by using function
__isnan(double x)
which can also be found on math.h, works correctly on cmdline compiler and Eclipse does not complain about it.
Related
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.
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.
I've got a problem with a cross-platform compile.
The code below compiles on Win, Mac and Linux (program is Qt based) but in order to make it compile on the Mac and Linux I have to defined if/else.
Windows compiler (VS2010) finds the definition but Mac (gcc4.2) and Linux (Ubuntu12LTS) cant find it...
Any ideas? Maybe Im missing some technical terminology in order to search for this?
I want to be able to use "table->setMark(i,MyObj());" for all systems as it doesnt seem to have any platform specific code.
///// .h
void setMark(int row, MyObj& mark)
{ value(row).setMark(mark); }
const MyObj& getMark(int row) const
{ return value(row).getMark(); }
/////
///// .cpp
MyObj obj;
bool ret = false, ifhandled = false;
m_root_command.evaluate(obj,ret,ifhandled);
if (m_marked) {
Table *table = m_thisobj.getTable();
for (int i = 0; i < table->getRowCount(); i++) {
#if defined(_WIN32)
// this works in windows, but fails to compile
// on other platforms with error below
table->setMark(i,MyObj());
#else
// I want to get rid of this workaround
// and use the above code for all platforms
MyObj objTmp = MyObj();
table->setMark(i,objTmp);
#endif
}
m_marked = false;
}
/////
///// Error
program.cpp: In member function 'MyObj Program::evaluate()':
program.cpp:264:36: error: no matching function for call to 'Table::setMark(int&, MyObj)'
program.cpp:264:36: note: candidate is:
table.h:326:9: note: void Table::setMark(int, MyObj&)
table.h:326:9: note: no known conversion for argument 2 from 'MyObj' to 'MyObj&'
make: *** [program.o] Error 1
/////
You cannot bind a temporary to a non-const reference. To use table->setMark(i,MyObj()); you need to change the declaration
void setMark(int row, MyObj& mark)
into
void setMark(int row, const MyObj& mark)
Likewise for the setMark that the function delegates to.
Edit: the fact it works in VS is apparently a known bug/feature
As far as I can see the problem resides in the #if clause.
#if defined(_WIN32)
table->setMark(i,MyObj());
#else
The setMark code it's only being executed on windows, because that's the only place where the #if defined(_WIN32) clause is true. If you remove the #if clause, it should work ok on both Mac OS and Linux.
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?
I am trying to compile the following very very simple piece of source code:
#include <cstring>
// #include <string.h>
// using namespace std;
class Helper {
public:
int cStringsAreEqual(const char *s1, const char *s2) {
return stricmp(s1, s2);
}
};
... but I am getting the following error message:
g++ error: ‘stricmp’ was not declared in this scope
However when I use strcmp() instead of stricmp() then everything is fine!
What can be wrong here? Shouldn't stricmp() be allowed when strcmp() is allowed?
Sureley, this all could be written in a much better way without using strcmp/stricmp.
But that's not the point here.
I am porting a piece of software - which makes much use of calls to stricmp(). And if somehow possible I would like to avoid all of the efforts needed to change every call to stricmp.
Any help on this would be very much appreciated!
BTW: I am using Ubuntu karmic OS (v9.10) with g++ v4.4.1.
BTW: as you can see I also made some trials with '#include string.h' or with 'namespace std' but nothing helped.
Try strcasecmp(). Here's the manual page for it. It is conforming to 4.4BSD and POSIX.1-2001.
stricmp is neither POSIX nor ANSI, so it doesn't really matter if strcmp is allowed, if your compiler or standard library is strictly adhering to POSIX or ANSI standard library functions (as is probably the case with the GCC suite).
Add a define for it to overwrite stricmp with strcasecmp on the platforms you are looking for.
#ifdef _IPHONE <- your platform define here
#define stricmp strcasecmp
#define strnicmp strncasecmp
#endif
Then you can just use stricmp always.
If you've got Boost, use boost::algorithm::iequals(s1, s2, std::locale::classic()) in <boost/algorithm/string/predicate.hpp> (or leave off locale if you want locale-sensitivity). It works with C strings, std::[w]string, vector<char>, etc.
Pretty easy to make your own if need be...
int my_stricmp (const char *s1, const char *s2)
{
while (*s1 != 0 && *s2 != 0)
{
if (*s1 != *s2 && ::toupper (*s1) != ::toupper(*s2))
{
return -1;
}
s1++;
s2++;
}
return (*s1 == 0 && *s2 == 0) ? 0 : -1;
}