

Found a bug in the GCC system (not deep, complex or new, but very frustrating) - RiderOfGiraffes
http://www.solipsys.co.uk/new/HuntTheBug.html?HN

======
RiderOfGiraffes
Right, I believe I now understand more of what's happening.

Prior to C99 there was no strtof. Some people may have rolled their own, but
it wasn't provided, you used strtod and cast to float if that's what you
wanted.

Then C99 included strtof, so the code (and hence symbol) became available in
the libraries. However, to avoid clashing with legacy code in which someone
used their own version, the prototype is only declared if the compiler is in
C99 mode.

That means that if you're not in C99 mode, you use the symbol strtof, and you
don't declare the function for yourself, the compiler successfully finds the
symbol in the library and links to the C99 code, but hasn't declared the
prototype, so you don't get what you think you get.

And by default you don't get warned.

To repeat the moral: use -Wall.

------
hga
And let's emphasize the last line of the posting:

" _The moral? Always use -Wall_ "

~~~
pmiller2
I always use "-W -Wall -ansi -pedantic". Substitute -std=c99 for -ansi if you
swing that way. I then run my code through a couple of other static checkers
just to see what comes up.

This frequently results in me finding some subtle bug which otherwise could
have taken hours of head scratching or single-stepping in gdb to locate.

~~~
hga
Yeah, I've been using "-Wall -Werror -Wstrict-prototypes -pedantic" as of late
and I clearly need to start thinking about a -std or -ansi.

C is a somewhat weak foundation for static program analysis but that doesn't
mean we can't try to make the most out of it.

------
jmillikin
Misleading headline -- GCC is behaving according to spec. It would have a bug
if the output had been 5.7 in both cases.

Arguably, allowing procedures to be called without prototypes is a bug in the
C spec, but I doubt it'll be removed any time soon simply due to sheer volume
of extant legacy code.

~~~
jrockway
It's strange, though. He includes stdlib.h, and according to my man pages:

    
    
       NAME
           strtod, strtof, strtold - convert ASCII string to floating-point number
     
       SYNOPSIS
           #include <stdlib.h>
    
           double strtod(const char *nptr, char **endptr);
           float strtof(const char *nptr, char **endptr);
    

Furthermore, here's stdlib.h:

    
    
        extern float strtof (__const char *__restrict __nptr,
                             char **__restrict __endptr) __THROW __nonnull ((1)) __wur;
    

Perhaps it works on my machine because I'm not using an out-of-date version of
GCC (gcc (Debian 4.4.4-2) 4.4.4)?

~~~
jey
Scroll down in your manpage to the "CONFORMS TO" section. You'll see that
strtof was only introduced in C99. This means that stdlib.h tests some macro
to determine whether it's in C99 mode before declaring the prototype for
strtof.

~~~
bobbyi
GCC doesn't use C99 mode by default? Is it going to become the default at some
point?

~~~
RiderOfGiraffes
To be fair, recent versions probably do. For reasons I won't (or can't) go
into, I have a tendency to be using slightly older systems. That's why I'm
more interested in finding out how things can be traced, rather than worrying
about this specific mis-match between my expectations and the system's
behavior.

------
tedunangst
Besides this not being a GCC bug, the explanation is also wrong.

"Apparently GCC has a built-in version of strtof, which it compiles into your
code if you're not using c99."

No, your libc has a function called strtof which the compiled program links
to. Just like any and every other external reference and completely
independent of where the prototype comes from.

~~~
RiderOfGiraffes
OK - I've edited the original, and will probably do so further as my
understanding increases.

Summary in a comment elsewhere in this submission.

------
kmak
I've been bit by this before -- in my case it was math.h and hypot. It was
quite frustrating to debug something that I assumed would be correct, so did
not look at.

