Including cmath and math.h and using isfinite(x)

Alec Jacobson

April 20, 2011

weblog/

I've been trying to compile a C++ program with a set of header files one a Solaris SPARC machine. It's my first experience with GCC outside of the usual intel/unix/mac world and it's been a bumpy ride. One problem that I had was that gcc on this machine doesn't seem to be using the same standards. This was easy to fix once I'd identified it as a problem: just add -ansi to the compiler flags. The code I'm compiling uses the std::isfinite function. On Macs gets included with cmath, but on the solaris machine it does not. Instead isfinite (notice that this time there is no std namespace) can be included from math.h. So fine, I change the headers to include from math.h instead of cmath and use isfinite instead of std::isfinite. But! I'm still getting the same old:
...: error: ‘isfinite’ was not declared in this scope
I looked and looked and finally found that earlier in the headers, before getting around to including math.h they include cmath. Including cmath then math.h apparently nukes any ability of retaining isfinite as a global function. Getting rid of other headers, here's a simple program that won't compile:
#include <cstdio>
#include <cmath>
#include <math.h>

int main(int argc,char * argv[])
{
  double b = 1.0;
  bool foo = isfinite(b);
  printf("isfinite(%g): %s\n",b,(foo ? "true" : "false"));

  b = 1.0/0.0;
  foo = isfinite(b);
  printf("isfinite(%g): %s\n",b,(foo ? "true" : "false"));

  return 0;
}
I compile with:
g++ test.cpp -o test -ansi
Okay, at this point I could try to get rid of the cmath include(s), but now I'm starting to mess with these headers a lot and I hadn't planned on having to edit them at all. Instead I came up with this solution. Before isfinite is used, I insert:

#define isfinite(x) !std::isinf(x)

Here's a test program that shows how it works:

#include <cstdio>
#include <cmath>
#include <math.h>
#define isfinite(x) !std::isinf(x)


int main(int argc,char * argv[])
{
  double b = 1.0;
  bool foo = isfinite(b);
  bool bar = isinf(b);
  printf("isfinite(%g): %s\n",b,(foo ? "true" : "false"));
  printf("isinf(%g): %s\n",b,(bar ? "true" : "false"));

  b = 1.0/0.0;
  foo = isfinite(b);
  bar = isinf(b);
  printf("isfinite(%g): %s\n",b,(foo ? "true" : "false"));
  printf("isinf(%g): %s\n",b,(bar ? "true" : "false"));

  return 0;
}
Now, of course, math.h is no longer necessary since we're not using its isfinite anyway. But the point is to show that it works with both cmath and math.h in the includes. Update: This doesn't work... I'm hopefully going to get back to this with something that does.