23 Программирование утверждений

We use cookies. Read the Privacy and Cookie Policy

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

Оскар Уайльд, Портрет Дориана Грея

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

"Этого никогда не случится…"

И далее: "Через 30 лет эта программа использоваться не будет, так что для обозначения года хватит и двух разрядов". "Нужна ли интернационализация, если это приложение не будет использоваться за рубежом?" "Счетчик не может принимать отрицательное значение". "Этот оператор printf не дает сбоев".

Не стоит заниматься подобного рода самообманом, особенно при написании программ.

Подсказка 33: Если что-либо не может произойти, воспользуйтесь утверждениями, которые гарантируют, что это не произойдет вовсе

Всякий раз, когда вы начинаете думать "Ну конечно, такого просто не может произойти", проверяйте это высказывание с помощью программы. Самый простой способ осуществить это – использовать утверждения. В большинстве реализаций языков С и С++ имеется некоторая разновидность макроса assert или _assert, который осуществляет проверку логического условия. Эти макрокоманды могут представлять огромную ценность. Если указатель, передаваемый к вашей процедуре, ни в коем случае не должен принимать значение NULL, то проверьте выполнение этого условия:

void writeString(char *string) {

   assert(string != NULL);

...

Утверждения представляют собой весьма полезное средство проверки работы алгоритма. Например, вы написали умный алгоритм сортировки. Проверьте, работает ли он:

For (int i=0; i<num_entries-1; i++) {

   assert(sorted[i] <= sorted[i+1]);

}

Конечно, условие, переданное утверждению, не должно оказывать побочного воздействия (см. врезку "Утверждения и побочные эффекты"). Необходимо также помнить, что утверждения могут отключаться во время компиляции – не помещайте в макрос assert программу, которая должна быть выполнена. Утверждения не должны использоваться вместо реальной обработки ошибок. Они лишь осуществляют проверку того, что никогда не должно произойти; вы же не хотите писать программу, подобную приведенной ниже:

printf("Enter 'Y' or 'N': ");

ch = getchar()

assert((ch=='Y')||(ch=='N')); /* дурной тон! */

И поскольку имеющаяся макрокоманда assert вызывает exit, если утверждение ложно, нет никаких оснований для того, чтобы этого не могли сделать создаваемые вами версии программы. Если вам приходится освобождать ресурсы, сделайте так, чтобы невыполнение утверждения возбуждало исключение или осуществляло переход longjump к точке выхода, или же вызывало обработчик ошибки. Убедитесь в том, что программа, которая исполняется в течение миллисекунд, не использует информацию, которая привела к невыполнению утверждений.