Thursday, October 21, 2010

Fixing errors with NAN (C const) and GCC

Today, I was compiling GEGL on a computer other than my regular one, and I got this wonderful error:
exp-combine.c: In function 'gegl_expcombine_new_exposure':
exp-combine.c:149: error: 'NAN' undeclared (first use in this function)
exp-combine.c:149: error: (Each undeclared identifier is reported only once
exp-combine.c:149: error: for each function it appears in.)
The error happens only on certain machines with some versions of gcc, and I it may happen in the most unexpected times...
So, I thought I'd share the solution for this problem with you since I had it in several more projects which use the NAN constant. Basically, NAN is a constant for a floating point value, which represents value that is Not A Number (not to be confused with the value which represents infinity). This value is usually (see note at the end) returned when dividing zero by zero, and therefore it can be added to gcc's definitions by adding the following argument to the command line:
-DNAN="(0.0/0.0)"
This is equivalent to adding the following line in C
#define NAN (0.0/0.0)
Now, there is only a little problem - what if we are not running GCC ourselves? What if a makefile or some other utility does this? Well, with most configure scripts (These scripts prepare the build environment and generate the makefiles) you can simply set the CFLAGS environment variable (before running the configure script) to fix this - in bash syntax this would be:
export CFLAGS="-DNAN=\"(0.0/0.0)\""
This solved my problems :)
Reference - http://old.nabble.com/Where-is-NAN-Defined--td15398150.html, http://linuxreviews.org/howtos/compiling/
As the original email list say, NAN is defined on some platforms and it's undefined on others, and our definition may not always work. From my experience, in the few cases were NAN wasn't defined, the fix presented here was enough.

Edit: I’d recommend checking the first comment below, from Martin Nordholts – he seems to offer another legitimate (and possibly more elegant) solution by telling GCC to use the gnu99 C standard.

3 comments:

  1. Hi Barak

    Another alternative is to use CFLAGS='-std=gnu99', that's what I use on the nightly build machine

    ReplyDelete
  2. Thank you!!!!!!!!!!! :)

    ReplyDelete
  3. Thank you!!! Came across this problem trying to compile gegl-0.1.8 just today on a slackware system with pretty much outdated and semi-updated libs & toolchain :)

    ReplyDelete