Неожиданный endptr с strtod()/strtold()
Я бы ожидал endptr
указать на то же значение с обоими strtod()
а также strtold()
, Все же они отличаются. Я подозреваю strtold()
это неверно. OTOH, это может быть случай, когда спецификация не ясна, и любой результат является приемлемым.
Это ошибка (и с какой функцией) или неопределенное / неопределенное поведение?
Использование: 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'
[Редактировать]
команда gcc 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
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'
Цитируя вещи из проекта N1570 стандарта C 2011...
Раздел 7.22.1.3 Пункт 3: Функции strtod, strtof и strtold
Ожидаемая форма предметной последовательности - необязательный знак плюс или минус, затем один из следующих:
- непустая последовательность десятичных цифр, необязательно содержащая символ десятичной точки, затем необязательная часть экспоненты, как определено в 6.4.4.2;
- ...
Раздел 6.4.4.2. Плавающие константы
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
определяется (акцент мой):
Функции strtod, strtof и strtold преобразуют начальную часть строки, на которую указывает nptr, в double, float и long double представление соответственно. Сначала они разбивают входную строку на три части: начальную, возможно пустую, последовательность символов пробела (как указано в
isspace
function) - предметная последовательность, напоминающая константу с плавающей точкой или представляющая бесконечность или NaN; и окончательная строка из одного или нескольких нераспознанных символов, включая завершающий нулевой символ входной строки. Затем они пытаются преобразовать последовательность объекта в число с плавающей запятой и вернуть результат.
И предметная последовательность определяется:
непустая последовательность десятичных цифр, необязательно содержащая символ десятичной точки, а затем необязательная часть экспоненты, как определено в 6.4.4.2.
И так как числовая часть после e
в вашем примере это нулевая длина, это не допустимая экспонентная часть.