Энциклопедия Turbo Pascal. Главы 9-11 - Переопределение встроенных процедур и функций

ОГЛАВЛЕНИЕ

Переопределение встроенных процедур и функций

Хотя Турбо Паскаль не допускает переопределения ключевых слов, которые входят в язык, он позволяет вам переопределять слова, которые отсылают к стандартным процедурам и функциям. Программисты иногда думают, что это интересно по многим причинам; однако, это может привести только к неприятностям. Далее дается пример проблемы, вызванной переопределением встроенной процедуры:

     program WRONG; {данная программа не вернa}
     var
       t: integer;
       units_processed: integer;

     procedure WriteLn(t: integer);
     begin
       write(t, ' ', 'байт свободной памяти в неупорядоченном
                   массиве');
     end;

     begin
       {вычислить объем свободной памяти в неупорядоченном
                        массиве}
       WriteLn(NemAvail);
       .
       .
       .
       WriteLn(units_processed);
     end.

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

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

     {проверить окно, оставшееся в глобальной матрице count }
     function MemAvail: boolean;
     var
       t: integer;

     begin
       MemAvail := FALSE;
       for t := 1 to MAX do if count[t]=0 then MemAvail:=TRUE;
     end;

Переопределение MemAvail  хорошо, пока выполняется данный пример. Проблема возникает, если матрица count превращается позднее из глобальной переменной в динамическую переменную, которая выделяется из неупорядоченного массива. В данном случае, если вы пытаетесь использовать MemAvail для просмотра того, осталось ли достаточно свободного пространства, ваша программа выйдет из строя.

Единственный способ избежать таких проблем заключается в том, чтобы никогда не иметь процедур и функций, написанных вами, с именами как у встроенных функций. Если вы не уверены, присоедините ваши инициалы в начало имени, например,  HSMemAvail  вместо MemAvail.