|
Выявление транслятором синтаксических ошибок представляет собой самый важный и безусловно необходимый этап отладки программы. Чем больше ошибок обнаруживается и исправляется на этом этапе, тем легче оказываются отладка и тестирование в дальнейшем. Начинающий программист наивно полагает, что на этапе компилирования выявляются все ошибки. Более опытный и придирчивый программист знает, что многие "хитрые" синтаксические ошибки транслятору обнаружить не под силу, и поэтому стремится обеспечить наиболее полное диагностирование таких ситуаций с выдачей в каждом конкретном случае подробной информации об ошибках.
Если под синтаксической ошибкой понимать "всякое нарушение требований языка программирования", то следует признать, что многие такие ошибки остаются необнаруженными. Это имеет место, например, при отсутствии указания начального значения какой-либо переменной, при наличии ответвления алгоритма в середину цикла оператора ЕЮ и в случае нарушения правил индексации. Результаты таких операций непредсказуемы, и если выполнить компилирование программы с такими ошибками, она будет работать самым таинственным образом. Выявление таких ошибок может оказаться делом нелегким. Отсутствие сообщений машины о синтаксических ошибках является необходимым, но не достаточным условием, чтобы считать программу правильной.
Обнаружение синтаксических ошибок важно по той причине, что они непременно приводят к затруднениям при выполнении программы. Более того, для компилятора требуется, чтобы эти ошибки были исправлены еще до начала пробного прогона программы.
В качестве примеров синтаксических ошибок в одном операторе можно назвать:
пропуск необходимого знака пунктуации;
несогласованность скобок;
пропуск нужных скобок;
неправильное формирование оператора;
неверное образование имен переменных;
неправильное использование арифметических операторов;
неверное написание зарезервированных слов.
Примерами синтаксических ошибок, охватывающих взаимодействие двух и более операторов, могут служить:
противоречивые команды;
отсутствие условий окончания цикла;
дублирование или отсутствие меток;
отсутствие описания массива;
запрещенный переход.
Если компилятор детально не анализирует взаимодействия двух или более команд, то нередко указанные выше ошибки остаются необнаруженными. Так, например, некоторые компиляторы не выдают программисту сообщений о непредусмотренном входе в цикл оператора ЭО.
Среди ошибок, которые часто выявляются компилятором в результате контроля синтаксической структуры программы, следует упомянуть неописанные или неправильно описанные переменные, опечатки и использование запрещенных символов.
Большинство синтаксических ошибок зависит от применяемого языка и используемой машины, поэтому мало что можно сказать конкретно по поводу способов их исправления в каждом конкретном случае. Однако можно указать некоторые общие принципы, которыми следует руководствоваться.
Во-первых, если в программе выявлено очень большое количество ошибок, следует просто исправить очевидные ошибки и повторить прогон. Некоторые сообщения о синтаксических ошибках являются на самом деле ложными, так как вызваны другими синтаксическими ошибками, и поэтому не стоит тратить много времени на то, чтобы разобраться в выданном сообщении, если характер ошибки не очевиден сразу. Ложные сообщения об ошибках особенно часты тогда, когда в программе имеет место какое-то серьезное упущение, например отсутствие описания переменной или массива.
Во-вторых, обращайтесь без колебаний к соответствующему руководству по программированию на данном языке: при неявных синтаксических ошибках чтение раздела, касающегося синтаксических правил для конкретных операторов, обычно приводит к выявлению допущенной ошибки.
В-третьих, большое внияние на объем работ по отладке оказывает выбор компилятора. Хороший отладочный компилятор может зачастую обеспечить сокращение затрат времени наполовину. Специальный отладочный компилятор обнаруживает больше ошибок, чем обычный, поскольку он детально анализирует синтаксическую конструкцию и взаимодействие-команд. Но еще важнее то, что в процессе выполнения исходной программы отладочный компилятор производит многочисленные проверки, выявляющие переменные, для которых не заданы начальные значения, неправильные индексы и запрещенные переходы. Разумеется, эти дополнительные проверки требуют большего времени, и поэтому процесс компилирования программы обычно осуществляется гораздо медленнее по сравнению с обычным компилятором.
Те пользователи, которые работают с языком ФОРТРАН, уже давно ощутили выгоды применения отладочного компилятора WATFIV. Практика его длительного использования доказала, что при наличии хорошего компилятора продолжительность отладки может быть значительно уменьшена, а ошибки при этом устраняются в самом начале создания программы.
Однако отладочные компиляторы не поставляются изготовителями ЭВМ в составе их программного обеспечения, их следует приобретать отдельно. Что касается стоимости таких компиляторов, то здесь оправданны любые затраты, так как если предположить, что отладка занимает 70% рабочего времени программиста и значительную долю машинного времени, то становится ясной быстрая окупаемость затрат на хороший отладочный компилятор.
Университет в Ватерлоо поставляет отладочные компиляторы WATBOL для КОБОЛа и WATFIV для ФОРТРАНа. В Корнелль-ском университете имеется подобный компилятор для языка ПЛ/1, который называется PL/C, а фирма IBM располагает для того же языка компилятором PL/1 Checkout. В Стэнфордском университете разработан компилятор АЛГОЛ W. Таким образом, все основные языки программирования снабжены отладочными компиляторами.
Применяйте отладочный компилятор.
4.11.1. ОШИБКИ, НЕ ОБНАРУЖИВАЕМЫЕ КОМПИЛЯТОРОМ
Существует множество ошибок, которые компилятор не в состоянии выявить, если используемые в программе соответствующие операторы сформированы правильно. Примерами таких ошибок являются:
пропуск части программы;
переход не на ту ветвь, на которую нужно, после выполнения оператора условного перехода;
использование неверного формата в операциях ввода данных;
неправильные параметры циклов (начальное состояние, приращение или конечное состояние);
неполная или неправильная индексация массива;
выпадение из рассмотрения некоторых возможных ситуаций,, связанных с данными и вычислениями.
Ниже приводится пример, показывающий почему ошибки индексирования не могут быть выявлены в процессе компилирования. Если некоторый массив насчитывает 10 элементов и индексы вычисляются с использованием переменных, то границы массива могут быть легко нарушены. Но нарушаются они-только в процессе выполнения программы. Так, если задан массив А (10) и
I = 4 * К А(1) = ...
то при К, большем 2, индекс массива окажется неправильным, однако этот факт не может быть установлен в ходе компилирования программы.
Среди других ошибок, не выявляемых при компилировании, следует назвать неправильный тип фактического параметра в операторах вызова, т. е. случаи, когда некоторая подпрограмма настроена, скажем, на целочисленный аргумент, а ей передается действительное число. Ошибку такого вида компилятор обнаружить не в состоянии, поскольку каждая из подпрограмм может компилироваться отдельно и в распоряжении компилятора нет информации, позволяющей проверить, совместимы ли типы аргументов вызываемой и вызывающей программ. Ошибку рассматриваемого вида можно выявить в процессе выполнения программы, либо если компилятором фиксируется информация относительно типа переменных, либо при использовании хорошего отладочного компилятора.
Если даже та или иная ошибка остается необнаруженной компилятором, из программы на входном языке все же будет получена объектная программа, однако эта программа будет неправильно завершаться в некоторой точке. Если же такого непредвиденного останова не произойдет, то результатом работы программы окажется выдача неверной информации, но этот факт никак не будет отмечен. Для обнаружения ошибок, пропущенных компилятором, служит тестирование программы.
Приведем еще несколько типов ошибок, которые могут выявляться (но редко выявляются), компилятором:
неиспользуемые метки;
неописанные переменные;
описанные, но не используемые переменные;
неверный тип аргумента функции;
неверный тип элемента в операторе формата.
Все эти ошибки могут быть обнаружены на этапе компилирования. Некоторые другие ошибки возможно выявить только в ходе выполнения программы. Ряд компиляторов позволяет генерировать вспомогательные блоки объектных программ (например, блок проверки диапазона изменения индексов), служащие для последующего контроля за ошибками определенного характера при выполнении программы. Чем больше имеется таких контрольных блоков, тем менее трудоемкой оказывается работа, связанная с устранением ошибок.
⇐4.10. Правильность программ || Оглавление || 4.12. Виды отладки⇒
Витамины вивасан. Выгодное предложение. |