Search code examples
chp-ux

HPUX atof doesn't convert string to double


I'm fetching the version number of an hpux machine and trying to convert it to a float using atof, but this happens:

#include <stdio.h>
#include <sys/utsname.h>

int main(int argc, char *argv[]) {
        struct utsname u;
        uname(&u);
        char* release = u.release;
        while (*release != '.')
                release++;
        release++;
        printf("%s\n", release);
        printf("%f\n", atof(release));
}

prints this:

# ./test
11.31
0.000000

Returning double 0 just means the conversion failed. The utsname man page says the strings are null terminated, so I don't understand why the atof command is failing. Am I making some kind of obvious mistake here?


Solution

  • The atof function is declared in <stdlib.h>.

    If you call it without the required #include <stdlib.h>, the most likely result is that (a) your compiler will print a warning (which you've apparently ignored), and (b) the compiler will assume that atof returns an int result.

    Add

    #include <stdlib.h>
    

    to the top of your source file. And pay attention to compiler warnings. If you didn't get a warning, find out how to invoke your compiler in a way that makes it warn about this kind of thing. (I don't know what compiler you're using, so I can't offer specifics.) For gcc, the compiler you're using, the -Wall option will enable this warning.

    Some background:

    Prior to the 1999 edition of the ISO C standard, it was permitted to call a function with no visible declaration. The compiler would assume that the function takes arguments of the (promoted) types passed in the call, and that it returns a result of type int. This typically would work correctly if the function actually does return an int, and if you write the call correctly (and if the function is not variadic, like printf).

    The 1999 version of the standard ("C99") dropped the "implicit int" rule, making any call to a function with no visible declaration a constraint violation, requiring a diagnostic (which can be a non-fatal warning). Many compilers, will merely warn about the error and then handle the call under the older rules. And gcc still doesn't enforce C99 rules by default; its default dialect is "GNU90", consisting of the 1990 ISO C standard plus GNU-specific extensions. You can ask it to use C99 semantics with "-std=c99"; to enforce those semantics, you can use "-std=c99 -pedantic" or "-std=c99 -pedantic-errors".

    Newer versions of gcc (partially) support the latest 2011 standard if you specify "-std=c11".

    See the gcc 4.8.2 manual for details.