Obscure C code (was Re: Excessive optimization)

Brian Lanning brianlanning at gmail.com
Thu Dec 2 21:03:25 CST 2010


On Thu, Dec 2, 2010 at 5:03 PM, Eric Smith <eric at brouhaha.com> wrote:
> Fred Cisin wrote:
> #include <stdio.h>
> int main ()
> {
>  int i;
>  for (i = 0; i < 14; i++)
>    putchar (i ["Hello, world!\n"]);
> }

That's awesome.  I didn't see at first that the loop pointer was being
used as an array.  For some reason it was invisible to me, I guess
because I wasn't expecting it.  But after seeing that, it became
somewhat more obvious to me.  :-)

This reminds me of a problem I once ran into on AIX.  I'm not sure if
the latest AIX implementation still has this issue, but it would be
easy to find out.  I was working on a rather large machine scheduling
system for brass foundries.  I had been in dbx for several hours
trying to track down a particularly nasty bug when I discovered that a
rather large calculation had a denominator of 0.  I stepped through
the line of code anyway expecting an error and instead got a plausible
value.  So I wrote this quick test program:

#include <stdio.h>
int main()
{
   int x, y, z;
   x = 1;
   y = 0;
   z = x / y;
   printf("%d\n", z);
}

Can anyone guess what the output was?    15.    Apparently, according
to AIX,   1/0 = 15.   At the time, I had access to an HPUX box, so I
ran the same program over there.  It crashed.  The error I got was
initially puzzling, but after a few minutes was the key to
understanding what was happening over on AIX.  The error over on HPUX
was "floating point exception".

My guess is that most C programmers wouldn't know that the divide
operator in C takes floats as parameters.  The compiler does an
implicit conversion from into to float on x and y, does the divide on
the floats (hence floating point exception), then converts the value
back to an int for storage in z.  It looks like when this implicit
conversion is done (on AIX) for the 0, instead of getting official
floating point zero, you instead get a close approximation.  This
approximation divided into 1 gets you a number that rounds to 15.
(2/0 yields 30)  And since dividing by zero is undefined, you get a
crazy answer.  So while technically correct, IBM really screws over
the programmer here.  In my opinion, floating point exception is the
correct behavior.  And it's what solaris and linux (and probably
windows) do also.  I was happy when we abandoned AIX.

brian



More information about the cctalk mailing list