Традиционный strtol()
обычно используется так:
int main()
{
errno = 0;
char *s = "12345678912345678900";
char *endptr;
long i = strtol(s, &endptr, 10);
if(i == LONG_MAX && errno == ERANGE)
printf("overflow");
}
Нам нужно получить доступ к errno
два раза, а errno
в настоящее время обычно представляет собой макрос C, который окончательно расширяется до функции. Это кажется немного дорогим, учитывая, что синтаксический анализ строки в целое число не является тяжелой работой.
Итак, не лучше ли реализовать strtol
без errno
, но используя какие-то другие способы индикации переполнения?
как:
long strtol(const char *nptr, char **endptr, int base, bool *is_overflow);
вместо
long strtol(const char *nptr, char **endptr, int base);
errno
, поэтому это невозможно сделать. Кроме того, вы потратите большую часть своего времени на алгоритм конвертации. Преобразование, вероятно, выполняется вO(n)
. Параметрerrno
выполняется вO(1)
. Параметрerrno
в основном не имеет значения. - person jww   schedule 09.12.2018errno
, как узнать, не было ли переполнения? - person DYZ   schedule 09.12.2018errno
равным нулю; -поскольку это rvalue, это было бы неправильно-. - person Shmuel H.   schedule 09.12.2018strol
, поэтому я задал этот вопрос. @DYZ спасибо, я отредактировал последнюю строку. - person weiweishuo   schedule 09.12.2018enptr
должно бытьendptr
. - person user202729   schedule 09.12.2018strtol.c
реализация от libc. - person jww   schedule 09.12.2018__errno_location
вызывается только один раз. - person user202729   schedule 09.12.2018-O2
местоположениеerrno
вычислялось и кэшировалось. С-O0
дважды вызывается__errno_location
. - person DYZ   schedule 09.12.2018endptr
. При использованииstrtol
у вас есть 2 проверки (1)if (s == endptr && i = 0) { /* error no digits converted */ }
, а затем (2)else if (errno) { /* over/underflow occurred */ }
. Итак, нет, не лучше избегать использованияerrno
. - person David C. Rankin   schedule 09.12.2018if (s == endptr && i = 0)
, а не простоif (s == endptr)
? - person chux - Reinstate Monica   schedule 09.12.2018if (s == endptr)
это нормально (и я уверен, что это так), но на странице руководства написаноif (s == endptr && i = 0)
, поэтому для полноты я включаю его. (например,"stores the original value of nptr in *endptr (and returns 0)"
) - person David C. Rankin   schedule 09.12.2018errno
не является хорошим методом сообщения об ошибках. Если вы не привязаны к существующему интерфейсу, лучше использовать другой метод. Не вызывайте свою функцию strtol и используйте любой метод, который вы хотите. Но strtol высечен в камне. - person n. 1.8e9-where's-my-share m.   schedule 09.12.2018LONG_MIN
илиLONG_MAX
, второе сравнение с участиемerrno
не требуется. В любом случае установленоerrno
и достаточно проверить, чтоerrno
не равно нулю. Кроме того, после установкиerrno
вы не подвергаетесь дополнительным штрафам за доступ к его значению (не больше, чем к доступу к значению любой переменной). - person David C. Rankin   schedule 09.12.2018strtol()
в коде C для вас нечестная гонка. Вы сталкиваетесь сstrtol()
, который реализован на C, ассемблере или чем-то еще и создан для быстрой работы на этой платформе. - person chux - Reinstate Monica   schedule 09.12.2018errno
гарантируется lvalue, фактическая реализация совершенно не имеет значения. Если это макрос, вызывающий функцию и разыменовывающий возвращаемыйint *
, компилятор может оптимизировать несколько вызовов. Оставьте такие оптимизации инструментальной цепочке, если у вас нет причин поступать иначе. Однако это едва ли когда-либо является узким местом. Не делайте преждевременных оптимизаций. Если у вас возникли проблемы с производительностью, профилируйте и оптимизируйте выявленные точки доступа. - person too honest for this site   schedule 09.12.2018errno
находится в TLS, поэтому обычно в таблице символов выполняется поиск, если потоки поддерживаются. Однако обычно это делается только один раз в функции (или даже в большем масштабе) и вряд ли является проблемой в реальном коде, особенно в контексте синтаксического анализа строк. - person too honest for this site   schedule 09.12.2018