# Hunt The Bug

From Colins Blog, and one of the Random Writings.

# Let's play Hunt the Bug ...

  #include #include #include int main( void ) { float f; double d; f = strtof("5.7",NULL); d = strtod("5.7",NULL); printf("F: %f\n", f); printf("F: %f\n",(double)f); printf("D: %f\n", d); printf("D: %f\n",(double)d); return 0; } 

OK, so here's a fun thing - what do you think that code should print?

It prints this:

• F: 3565158.000000
• F: 3565158.000000
• D: 5.700000
• D: 5.700000

That surprised me.

In case you're interested:

• gcc version 4.1.0 (SUSE Linux)
• SUSE LINUX 10.1 (i586)
• VERSION = 10.1

It works with this command:
• gcc -std=c99 bug.c

So here's the thing.

 I've been corrected about this. Apparently it's not thought of as being "built in" if the code is in libc. So I stand (or sit) corrected. The code for strtof is in libc, or some library (as yet not exactly pinned down) but the prototype isn't in strlib.h. The reason is becoming clear now. strtof wasn't in the original C and has only been introduced in C99. Since it is in C99 the code exists. Since it's not in earlier versions the prototype isn't declared unless you're in C99 mode. So there you are.
Apparently GCC has a built-in version of strtof, (corrected - see side-box) which it compiles into your code if you're not using C99. (Because before C99 there was no strtof in the standard library).

However, the built-in version of strtof doesn't have a prototype unless you are in C99 mode, just in case you made one of your own, and hence the system defaults to returning an int.. But now one part of the compiler thinks it's an int, another thinks it's a float, and everything goes to hell in a handbasket.

So there are three ways to get answers you expect instead of random numbers:

• Compile with the c99 option as above,
• Provide a prototype: float strtof(char *, char * *);
• Use doubles.

The moral? Always use -Wall

Or don't use C.