07 июня 2011

Магические числа

Привет. Знаком ли вам антипаттерн магические числа? Да наверняка. И все с этим сталкиваются. Чаще всего появление магического числа можно предотвратить в зачатке, иногда нет. Бывает что оно достается нам в наследство. Согласен, наследство дурное, но править что-то в незнакомом коде очень сложно. Я раньше старался делать правки только если они сильно затрагивают мой код, остальное старался оставить как можно ближе к оригиналу.

Я был не прав. Магические числа, а так же дублирование которое они вызывают, нужно устранять по возможности сразу. Шишек от этого может насыпаться очень много. Почему по возможности, потому что не всегда эта возможность есть, иногда, когда вам говорят что сроки давят и надо быстрее, сроки действительно давят и надо быстрее. Быстрее, не значит хуже. Просто иногда бросаться править магические числа сразу не стоит, но потом нужно обязательно к ним вернуться.

И никогда не оставляйте магические числа на месте, даже на потом, когда вы начинаете их использовать. Один раз или даже половину, не важно. В этом случае никакого потом быть не должно, сразу и точка.

Я не буду недооценивать боль и страдания которые несут в себе магические числа.
Я не буду недооценивать боль и страдания которые несут в себе магические числа.
Я не буду недооценивать боль и страдания которые несут в себе магические числа.
Я не буду недооценивать боль и страдания которые несут в себе магические числа.
Я не буду недооценивать боль и страдания которые несут в себе магические числа.
Я не буду недооценивать боль и страдания которые несут в себе магические числа.
Я не буду недооценивать боль и страдания которые несут в себе магические числа.
Я не буду недооценивать боль и страдания которые несут в себе магические числа.
Я не буду недооценивать боль и страдания которые несут в себе магические числа.
Я не буду недооценивать боль и страдания которые несут в себе магические числа.

02 июня 2011

Арифметическое переполнение

Привет. А вот используете ли вы вот такие проверки:

#if 0
RAND=$RANDOM
gcc -o $RAND $0 && ./$RAND
rm $RAND
exit
#endif
#include <stdio.h>
#include <limits.h>

void
check_overflow(unsigned int count, unsigned int added)
{
  if ((UINT_MAX - count) > added)
    printf("%2ld + %2ld > %ld | OK!\n", count, added, UINT_MAX);
  else
    printf("%2ld + %2ld > %ld | Overflow!\n", count, added, UINT_MAX);
}

int
main(int argc, char** argv)
{
  unsigned int count = UINT_MAX - 10;
  unsigned int overflow = 15;
  unsigned int no_overflow = 5;

  check_overflow(count, overflow);    // Overflow!
  check_overflow(count, no_overflow); // OK!
  return 0;
}

Ну? А надо бы. Для растущих переменных лучше такую проверку делать. Зачем? Число то большое. Такого никогда не случиться. Мир идеален. Цой просто гостит у Элвиса. Так вот, если в этом числе копить миллисекунды времени (или чего еще), то через 49.8 дней (примерно) случиться арифметическое переполнение. А оно вам надо? Думаю нет. Пишите не только работающий, но и надежно работающий код, когда такая возможность есть. Иногда, да, приходиться писать просто работающий код. Но думать какие значение хранит переменная и какие самые страшные значения она может принять думать надо всегда.

P.S. И да. Танки судьбы очень скоро продолжат свое развитие.