Лучше ли реализовать strtol () без errno? - PullRequest
0 голосов
/ 09 декабря 2018

Традиционный 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);

Ответы [ 2 ]

0 голосов
/ 09 декабря 2018

На самом деле есть некоторые издержки, кроме errno в strtol(), такие как пропуск пробелов, уход за основанием (10 или гекса), проверка символов ...

В конкретной среде, где скорость критична, а вы знаете, что предоставленная строка представляет собой числовую базу 10 , которая вписывается в long, вы можете сделать свою собственную быструю функцию, например

#include <ctype.h>

long mystrtol(char *s) {
   long res = 0, minus = *s == '-';
   if (minus || *s == '+') s++;

   while (isdigit(*s)) {
      res = res*10 + (*s++ - '0');
   }

   return minus ? -res : res;
}

и выберите встроить его.

0 голосов
/ 09 декабря 2018

лучше ли реализовывать strtol без errno ...

Нет.

... но использовать другие способы указания переполнения?

Нет.

long int strtol(const char * restrict nptr, char ** restrict endptr, int base);

strtol() - это стандартная функция библиотеки C, и любая реализация должна придерживаться правильного использования 3-х входов и errno, чтобы соответствовать.


Конечно, OP может реализовывать некоторые другие my_strtol() по желанию.

Любые проблемы с производительностью, связанные с отказом от errno, являются микрооптимизацией, но при этом разумной целью проектирования.* Это действительно сводится к тому, как передать проблемы строки в long

  • Переполнение "12345678912345678901234567890"

  • Без преобразований "abc"

  • Избыточный мусор "123 abc"

  • Разрешены начальные пробелы, разрешены пробелы?

  • Разрешить различные базы?

После определения функциональности во всех исключительных случаях, а не просто переполнения, полезны проблемы кодирования относительно errno, даже если вряд ли внесет какие-либо существенные улучшения производительности.

IMO, кодирование только на одну базу, скорее всего, более продуктивный путь к повышению скорости, чем errno.


OP-код не является надежным strtol() использованием.Предложить:

char *s = "12345678912345678900";

char *endptr;
errno = 0;
long i = strtol(s,  &endptr, 10);
if (errno == ERANGE) printf("Overflow %ld\n", i);
else if (s == endptr) printf("No conversion %ld\n", i);
else if (*endptr) printf("Extra Junk %ld\n", i);
else printf("Success %ld\n", i);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...