带有 strtod()/strtold() 的意外 endptr
Unexpected endptr with strtod()/strtold()
我希望 endptr
与 strtod()
和 strtold()
指向相同的值。然而他们不同。我怀疑 strtold()
不正确。 OTOH,这可能是规范不明确并且任一结果都可以接受的情况。
这是错误(以及与哪个函数有关)还是 undefined/unspecified 行为?
使用:gcc\x86_64-pc-cygwin.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'
[编辑]
gcc 命令 gcc -I"C:\cygwin64\lib\gcc\x86_64-pc-cygwin.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"
海湾合作委员会 4.9.2
都不应该消耗 e
。要允许使用 e
,e
之后必须有一个非空的数字序列。 GCC 4.9.0 与 Glibc 2.12 的行为正确。
[2:29pm][wlynch@apple /tmp] ./a.out
double 123.000000 'ez'
long double 123.000000 'ez'
引用 C 2011 标准草案 N1570 中的内容...
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
我认为这是您 运行 反对的 C 标准库中的错误。
这是 strtold
的错误 - 标准将常数的指数部分的语法定义为 (6.4.4.2):
exponent-part:
e sign(optional) digit-sequence
E sign(optional) digit-sequence
其中:
digit-sequence:
digit
digit-sequence digit
并且 digit
被定义为不能为零长度。所以 e
之后的数字部分不能是零长度。
定义了 strtold
的行为(强调我的):
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.
主题序列定义为:
a nonempty sequence of decimal digits optionally containing a
decimal-point character, then an optional exponent part as defined in
6.4.4.2.
并且由于您示例中 e
之后的数字部分是零长度,因此它不是有效的指数部分。
我希望 endptr
与 strtod()
和 strtold()
指向相同的值。然而他们不同。我怀疑 strtold()
不正确。 OTOH,这可能是规范不明确并且任一结果都可以接受的情况。
这是错误(以及与哪个函数有关)还是 undefined/unspecified 行为?
使用:gcc\x86_64-pc-cygwin.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'
[编辑]
gcc 命令 gcc -I"C:\cygwin64\lib\gcc\x86_64-pc-cygwin.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"
海湾合作委员会 4.9.2
都不应该消耗 e
。要允许使用 e
,e
之后必须有一个非空的数字序列。 GCC 4.9.0 与 Glibc 2.12 的行为正确。
[2:29pm][wlynch@apple /tmp] ./a.out
double 123.000000 'ez'
long double 123.000000 'ez'
引用 C 2011 标准草案 N1570 中的内容...
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
我认为这是您 运行 反对的 C 标准库中的错误。
这是 strtold
的错误 - 标准将常数的指数部分的语法定义为 (6.4.4.2):
exponent-part:
e sign(optional) digit-sequence
E sign(optional) digit-sequence
其中:
digit-sequence:
digit
digit-sequence digit
并且 digit
被定义为不能为零长度。所以 e
之后的数字部分不能是零长度。
定义了 strtold
的行为(强调我的):
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.
主题序列定义为:
a nonempty sequence of decimal digits optionally containing a decimal-point character, then an optional exponent part as defined in 6.4.4.2.
并且由于您示例中 e
之后的数字部分是零长度,因此它不是有效的指数部分。