Няшная / Говнокод #10235 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
short lPort = atoi(szTemp);
if (lPort <= 0 || lPort > 65535)
	lPort = 80;

Запостил: absolut absolut, (Updated )

Комментарии (9) RSS

  • Как обычно, говонокодовость заключается в первой строчке: в самом факте использовании функции 'atoi', а также в бездумном запихивании int-овго результата в переменную типа 'short'.

    Все остальное - малозначительные детали.
    Ответить
        • Ну это воообще-то единый стандарт для всех функция конвертации в стандартной библиотеке: допустимая входная строка имеет вид '[пробелы]<число>[всякий мусор]'. Но если хочется отлавливать ситуации со "всяким мусором" в конце, то, конечно, функции группы 'strto...' подходят хорошо.

          По моему мнению, основная проблема с 'atoi' не в этом, а в том, что функция порождает неопределенное поведение при переполнении и тупо возвращает '0' при некорректном формате входа.
          Ответить
          • Тупо возвращение 0 не так уж и ужасно - например для выдачи сообщения "Порт должен быть целым числом в диапазоне от 1 до 65535" этого вполне достаточно. А вот неопределенное поведение при переполнении и игнор мусора в конце - это да, проблема.
            Ответить
      • Функции группы 'ato...' не дают никакого способа отлова ошибок при конвертации. Некорректный вход приводит к возврату '0'. И разбирайся потом, был ли там на входе именно '0', или произошла ошибка. Но это еще полбеды. Вторая проблема - при переполнении они вызывают неопределенное поведение. От этого никакой защиты нет.

        Это часто умиляет в пионэрском говнкоде, когда пионэр осознает наличие проблемы, и для ее "решения" воздвигает вокруг вызова 'atoi' горы дополнительного кода, призванного проверять как коректность формата, так и непереполняемость результата. При этом сложность этого нагромождения кода обычно на порядки превышает сложность самого 'atoi' и, как правило, содержит внутри себя еще одну неявную реализацию 'atoi' вручную 🙂

        На самом деле функции группы 'ato...' никакой практической ценности не представляют. Другой способ конвертации строк в число - функция 'sscanf' - несколько лучше, но тоже вывзвает неопределенное поведение при переполнении.

        Единственно правильный способ перевода строки в число - это функции группы 'strto...'. Пользуйтесь 'strtol' и забудьте навсегда про существование 'atoi'. Функции группы 'strto...' для того и были введены, чтобы люди перестали мучать этот несчастный 'atoi'.

        P.S. В коде "продвинутых" пионэров встречается даже варианты, когда присле вызова 'atoi' и получения нуля в ответ делается вызов 'strtol', чтобы выяснить, что случилось 🙂
        Ответить
  • "Из исходников windows firewall" - как-то само напрашивается 🙂
    Ответить
  • glibc 2.14
    /* Convert a string to an int.  */
    int
    atoi (const char *nptr)
    {
      return (int) strtol (nptr, (char **) NULL, 10);
    }
    Ответить

Добавить комментарий

Семь раз отмерь — один отрежь, guest!

    А не использовать ли нам bbcode?


    8