Reputation: 153582
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
Upvotes: 4
Views: 420
Reputation: 5502
It's a bug with strtold
- the standard defines the syntax of an exponent part of a constant as (6.4.4.2):
exponent-part:
e sign(optional) digit-sequence
E sign(optional) digit-sequence
Where:
digit-sequence:
digit
digit-sequence digit
And digit
is defined so that it can't be zero-length. So the numeric part after the e
can't be zero-length.
The behavior of strtold
is defined (emphasis mine):
The strtod, strtof, and strtold functions convert the initial portion of the string pointed to by nptr to double, float, and long double representation, respectively. First, they decompose the input string into three parts: an initial, possibly empty, sequence of white-space characters (as specified by the
isspace
function), a subject sequence resembling a floating-point constant or representing an infinity or NaN; and a final string of one or more unrecognized characters, including the terminating null character of the input string. Then, they attempt to convert the subject sequence to a floating-point number, and return the result.
And the subject sequence is defined:
a nonempty sequence of decimal digits optionally containing a decimal-point character, then an optional exponent part as defined in 6.4.4.2.
And since the numeric part after the e
in your example is zero-length, it isn't a valid exponent part.
Upvotes: 3
Reputation: 81936
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.
Upvotes: 4