cgccstrtod

Unexpected endptr with strtod()/strtold()


I'd expect the endptr to point to the same value with both strtod() and strtold(). Yet they differ. I suspect strtold() is incorrect. OTOH, this could be a case where the spec is not clear and either result is acceptable.

Is this a bug (and with which function) or undefined/unspecified behavior?

Using: gcc\x86_64-pc-cygwin\4.8.3

#include <math.h>
#include <stdio.h>

// Edit - This include is in my true code, but was missing in original post
#include <stdlib.h>

int main(void) {
    char *s = "123ez";
    char *endptr;
    double d = strtod(s, &endptr);
    printf("     double %f '%s'\n", d, endptr);
    long double ld = strtold(s, &endptr);
    printf("long double %Lf '%s'\n", ld, endptr);
    return 0;
    }

Output:
     double 123.000000 'ez'
long double 123.000000 'z'

[Edit]

gcc comand gcc -I"C:\cygwin64\lib\gcc\x86_64-pc-cygwin\4.8.3\include" -O0 -g3 -Wall -c -fmessage-length=0 -std=c99 -MMD -MP -MF"string_fp.d" -MT"string_fp.d" -o "string_fp.o" "../string_fp.c"

GCC 4.9.2


Solution

  • Neither should consume the e. To be allowed to consume the e, there must be a non-empty sequence of digits after the e. And GCC 4.9.0 with Glibc 2.12 behaves correctly.

    [2:29pm][wlynch@apple /tmp] ./a.out 
         double 123.000000 'ez'
    long double 123.000000 'ez'
    

    Citing things from draft N1570 of the C 2011 standard...

    Section 7.22.1.3 Paragraph 3: The strtod, strtof, and strtold functions

    The expected form of the subject sequence is an optional plus or minus sign, then one of the following:

    • a nonempty sequence of decimal digits optionally containing a decimal-point character, then an optional exponent part as defined in 6.4.4.2;
    • ...

    Section 6.4.4.2 Floating Constants

    exponent-part:
        e signopt digit-sequence
        E signopt digit-sequence
    digit-sequence:
        digit
        digit-sequence digit
    

    I would consider this a bug in the C standard library that you are running against.