4 ms·
Found a bug in the GCC system (not deep, complex or new, but very frustrating)
- kmak 16y agoI'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.
- hga 16y agoAnd let's emphasize the last line of the posting: "The moral? Always use -Wall"
- ciupicri 16y agoBtw, is there a GCC specific way to disable warnings for some portions of code?
- shabble 16y agohttp://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html http://gcc.gnu.org/onlinedocs/gcc/Diagnostic-Pragmas.html should get you most of the way there.
- pmiller2 16y agoI 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 16y agoYeah, 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.
- astrange 16y ago"-Werror=implicit" would be more useful here. -Wall won't prevent that from compiling, but there's hardly any situation where you'd want it to compile.
- jmillikin 16y agoMisleading 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 16y agoIt'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 16y agoScroll 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 16y agoGCC doesn't use C99 mode by default? Is it going to become the default at some point?
- RiderOfGiraffes 16y agoTo 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 16y agoBesides 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 16y agoOK - I've edited the original, and will probably do so further as my understanding increases. Summary in a comment elsewhere in this submission.
- RiderOfGiraffes 16y agoRight, 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.