title: Strange bug in usage of abs() I encountered recently
body: <p>I have C++/C mixed code which I build on</p>
  
  <p>a) Visual C++ 2010 Express(Free version) on Win-7 x32.</p>
  
  <p>b) Cygwin/Gcc environment installed on a Windows-7 Home premium edition x32. The gcc version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)</p>
  
  <p>c) Ubuntu 10.04 Linux- GCC version 4.4.3 (Ubuntu 4.4.3-4ubuntu5)</p>
  
  <p>I have a code as below(Its a member function for my user defined class) which computes absolute value of the passed object myhalf-</p>
  
  <pre><code>myhalf::myhalfabs(myhalf a)
  {
      float tmp;   
      tmp = abs(a.value); //This abs is from math.h :-  float abs(float)
      return tmp;
  }
  </code></pre>
  
  <p>This is working perfectly as desired in MS - Visual C++ 2010. abs() of -ve nos were returned correctly as +ve nos having same value.
  Strangely when I built this code on b) Cygwin/gcc environment &amp; c) Linux-gcc 4.4.3 mentioned above, I was getting junk output. So fired up gdb, and after lot of sweat and 'binary-search approach' on the code to decide where it started going wrong, I hit this piece of code as shown above :</p>
  
  <pre><code>tmp = abs(a.value);
  </code></pre>
  
  <p>which was behaving strangely under cygwin/gcc.</p>
  
  <p>For -ve numbers abs() was returning 0(zero).  WTF??</p>
  
  <p>Then as a work around, avoided calling abs() from stdlib, and coded my own abs as below:</p>
  
  <pre><code>myhalf::myhalfabs(myhalf a)
  {
      float tmp;
      unsigned int tmp_dbg;
      // tmp = abs(a.value);
      tmp_dbg = *(unsigned int*)(&amp;a.value);
      tmp_dbg = tmp_dbg &amp; 0x7FFFFFFF;
      tmp = *(float*)(&amp;tmp_dbg);
  
      return tmp;
  }
  </code></pre>
  
  <p>This worked fine on cygwin/gcc &amp; linux-gcc and output was as desired, And of course it worked fine on MS-Visual C++ 2010.</p>
  
  <p>This is the whole Makefile for the cygwin/gcc and linux-gcc builds, I use. Just if anyone supspects something fishy there:-</p>
  
  <pre><code>OBJS= &lt;all my obj files listed here explicitly&gt;
  
  HEADERS= &lt;my header files here&gt;
  CFLAGS= -Wall
  LIBS= -lm
  LDFLAGS= $(LIBS)
  
  #MDEBUG=1
  ifdef MDEBUG
  CFLAGS += -fmudflap
  LDFLAGS += -fmudflap -lmudflap
  endif
  
  myexe:    $(OBJS)
      g++ $(OBJS) $(LDFLAGS) -o myexe
  
  %.o:    %.cpp $(HEADERS) Makefile
      g++ $(CFLAGS) -c $&lt;
  
  clean:
      rm -f myexe $(OBJS)
  </code></pre>
  
  <hr>
  
  <p>1] What is going on here? What is the root cause of this strange bug?</p>
  
  <p>2] Am i using some old version of gcc on cygwin which has this issue as known bug or something?</p>
  
  <p>3] Is this function float abs(float) known to be deprecated or something with a newer version superseding it?</p>
  
  <p>Any pointers are useful.</p>