Чтобы подкрепить наши утверждения о том, что для отладки необходимо знать намерения программиста, рассмотрим основные альтернативы такого подхода к организации отладки и покажем, почему они не годятся. Мы рассмотрим такие методы, как анализ соотношения вход — выход, анализ потоков данных и распознавание типичных ошибочных отрезков программ.
Отладка путем анализа поведения программы в зависимости от входа сводится к определению случаев, когда выход программы оказывается неправильным, и к выдвижению гипотез относительно ошибок, которые могли бы привести к неправильному поведению программы. При использовании этого метода отладки последняя напоминает постановку диагноза в медицине: неверное поведение программы можно считать симптомом, а сами ошибки — «заболеванием». Такой подход связан с двумя затруднениями: не всегда удается выделить симптомы, характеризующие плохую программу, и не всегда симптомы удается связать с ошибками.
Ошибки, содержащиеся в программах, приведенных на рис. 1,а и 2,а, лишь иногда сказываются на выходе программы, а чтобы узнать, когда именно это происходит, необходимо представлять себе, каким в действительности должен быть выход. Поскольку в примере «путаница WHILE с IF» программе не удается заметить недопустимость отрицательного входного значения, после того как будет напечатано положительное число, то естественно возникает предположение, что в программе пропущена проверка на допустимость входных величин. И только ознакомившись с текстом программы, можно понять, что ошибка не в отсутствии такой проверки, а в организации проверки на наличие сигнального значения.
В качестве другого подхода к отладке программы можно было бы рассмотреть анализ потоков данных. Он используется во многих компиляторах, обнаруживающих ошибки в программе. В ходе анализа потоков данных ищутся явные аномалии в характере определения данных и их последующего использования в программе. При этом удается обнаружить, что какая-то переменная не определена или что переменная определена, но нигде не используется. Однако если в потоках данных нет отклонений от нормы, то такой анализ никаких ошибок не обнаружит. Ни в одном из примеров, приведенных в предыдущем разделе, нет нарушений в потоках данных; следовательно, при этом подходе найти ошибки не удастся.
Можно также попытаться проанализировать структуру самой программы в надежде, что это наведет на мысль о наличии ошибок. Можно было бы создать библиотеку шаблонов для наиболее распространенных ошибок типа пропуска проверки на сигнальные значения или использования операторов WHILE вместо IF, и затем в поиске ошибок сличить эти шаблоны с программой. При таком подходе, однако, невозможно узнать, с каким именно местом в программе следует сличать шаблоны ошибок. Так, в примере путаницы «WHILE с IF» имеются три различных цикла, содержащие WHILE. Как можно узнать, в каком из этих циклов вместо WHILE должно быть IF? А возможно, везде следует сохранить операторьг WHILE? Можно было бы сделать шаблон более специализированным, договорившись, что он применяется лишь в случае, когда имеются два цикла, расположенных один в другом и обладающих общей выходной проверкой. Но такой слишком специализированный шаблон был бы неприменим и других случаях, где WHILE появляется вместо IF.
Во всех описанных подходах к отладке делается попытка выделить ошибки без понимания того, что ожидается от программы; вследствие этого не удается уйти далеко от просто догадок о возможном характере ошибок. Чтобы достигнуть большего, система отладки должна быть способной выяснить намерения программиста и сопоставить их с текстом программы.