П3.
СООБЩЕНИЯ И КОДЫ ОШИБОК
П3.1. СООБЩЕНИЯ
ОБ ОШИБКАХ ПЕРИОДА КОМПИЛЯЦИИ
Среда Турбо Паскаля дает исчерпывающую
информацию о характере и месте обнаруженной
компилятором ошибки. При обнаружении
ошибки среда автоматически загружает
в окно редактора исходный файл и помещает
курсор около того места, где в исходном
тексте обнаружена ошибка. При этом в
верхней строке редактора появляется
диагностическое сообщение. После нажатия
на любую клавишу (кроме FI) верхняя строка
восстанавливает свой первоначальный
вид и среда переходит к режиму
редактирования. Если после появления
сообщения об ошибке нажать F1, на экране
появится окно справочной службы с
детальной информацией об ошибке и
рекомендациями по ее устранению.
Некоторые ошибки в исходном тексте
обнаруживаются не сразу, а в ходе
продолжающегося контекстного разбора.
Например, несоответствие типов в
операторе присваивания не может быть
обнаружено до тех пор, пока не будет
вычислено целиком выражение в правой
части этого оператора. В таких случаях
ищите ошибку слева от курсора или в
предыдущей строке текста.
Ниже приводятся сообщения об ошибках
в том виде, в каком они появляются в
верхней строке редактора, а также перевод
сообщений справочной службы.
На экране после кода ошибки (цифры) нет
точки, поэтому ее нет и в соответствующем
месте текста.
1 Out of memory (Выход
за границы памяти).
Компилятору не хватает памяти. Имеется
ряд возможных решений этой проблемы:
-
если в опции COMPILE/DESTINATION установлено
значение MEMORY, замените эту опцию на
DISK; -
если в опции OPTIONS/LINKER/LINK BUFFER установлено
значение MEMORY, замените эту опцию т DISK; -
если Вы используете резидентные
обслуживающие программы, такие как
SIDEKICK, NORTON, удалите их из памяти; -
если Вы используете интегрированную
среду TVRBO.EXE, то попробуйте воспользоваться
компилятором ТРС.ЕХЕ — он занимает
меньше памяти.
Если ни одна из рекомендаций не помогает,
то, возможно, Ваша программа просто
слишком велика, чтобы компилировать ее
в таком объеме памяти. В этом случае Вы
должны разбить ее на два или более
модулей.
2 Identifier
expected (He указан
идентификатор).
В этом месте должен находиться
идентификатор. Возможно, Вы пытаетесь
использовать в качестве идентификатора
зарезервированное слово.
3 Unknown identifier (Неизвестный
идентификатор).
Этот идентификатор не был описан.
4 Duplicate identifier (Двойной
идентификатор).
Попытка дважды описать один и тот же
идентификатор.
5 Syntax error (Синтаксическая
ошибка).
В исходном тексте найден недопустимый
символ. Возможно, Вы забыли заключить
в апострофы строковую константу.
6 Error in real constant (Ошибка
в вещественной константе).
Синтаксис констант вещественного типа
описан в гл.4.
7 Error in integer constant
(Ошибка в целой константе).
Синтаксис констант целого типа описан
в гл.4. Учтите, что после целых действительных
чисел, превышающих диапазон представления
целых чисел (-2147483648..+2147483647), должны
ставиться точка и ноль, например,
12345678912.0.
8 String constant exceeds line
(Строковая константа превышает допустимые
размеры).
Вероятно, Вы забыли поставить апостроф
в конце строковой константы.
9 Too many nested files (Слишком
много вложенных файлов).
Компилятор допускает не более пяти
уровней вложенности включаемых файлов
(т.е. в исходном файле есть ссылка на
включаемый файл, в котором есть ссылка
на еще один включаемый файл и т.д.).
10 Unexpected end of file (He
найден конец файла).
Вы могли получить это сообщение об
ошибке по одной из следующих причин:
-
Ваш исходный файл закончился перед
последним END основного раздела операторов;
вероятно, в Вашей программе неодинаковое
количество операторов BEGIN и END; -
включаемый файл заканчивается в середине
раздела операторов; каждый раздел
операторов должен целиком помещаться
в одном файле; -
Вы не закончили комментарий.
11 Line too long (Слишком
длинная строка).
Максимальная длина строки, обрабатываемой
компилятором, равна 126 символам (обратите
внимание: редактор среды может обрабатывать
строки практически неограниченной
длины).
12 Type identifier expected
(Здесь нужен идентификатор типа).
Не указан тип идентификатора.
13 Too many open files (Слишком
много открытых файлов).
Появление этой ошибки означает, что
конфигурационный файл CONFIG.SYS операционной
системы не включает параметр FlLES=xx или
этот параметр указывает слишком мало
файлов. Увеличьте число файлов до нужного
значения, например, до 80.
14 Invalid file name (Неверное
имя файла).
Имя файла неверно или указан несуществующий
путь.
15 File not found (Файл не
найден).
Файл не был найден в просмотренных
каталогах.
16 Disk full (Диск
заполнен).
Удалите некоторые файлы или воспользуйтесь
новым диском.
17 Invalid compiler directive
(Неправильная директива компилятора).
Неверная буква в директиве компилятора,
один из параметров директивы компилятора
неверный, или Вы пользуетесь глобальной
директивой компилятора, когда компиляция
тела программы уже началась.
18 Too many files (Слишком
много файлов).
В компиляции программы или программного
модуля участвуют слишком много файлов.
Попытайтесь не использовать так много
файлов, например, объединяя включаемые
файлы или делая короче имена файлов.
19 Undefined type in pointer
definition (Неопределенный тип в объявлении
указателя).
Попытка объявить типизированный
указатель, связанный с ранее не объявленным
типом данных.
20 Variable identifier expected
(Отсутствует идентификатор переменной).
На этом месте должен быть идентификатор
переменной.
21 Error in type (Ошибка в
объявлении типа).
Объявление типа не может начинаться с
этого символа.
22 Structure too large (Слишком
большая структура).
Максимально допустимый размер любого
структурного типа составляет 65520 байт.
23 Set base type of range
(Базовый тип множества нарушает границы).
Базовый тип множества должен представлять
собой тип-диапазон с границами в пределах
от 0 до 255 или перечисляемый тип с не
более чем 256 значениями.
24 File components may not be files (Компонентами файла
не могут быть файлы) .
Конструкции типа file of file (файл файлов)
или file of object (файл объектов) не допускаются.
Нельзя объявлять любые структурные
типы, которые используют в качестве
компонентов объекты или файлы.
25 Invalid string length
(Неверная длина строки).
Объявляемая длина строки должна
находиться в диапазоне от 1 до 255.
26 Type mismatch (Несоответствие
типов).
Это сообщение может быть вызвано
следующими причинами:
-
несовместимые типы переменной и
выражения в операторе присваивания; -
несовместимые типы фактического и
формального параметров в обращении к
процедуре или функции; -
тип выражения не совместим с типом
индекса при индексировании массива; -
несовместимые типы операндов в выражении.
27 Invalid subrange base
type(Неправильный базовый тип для
типа-диапазона).
Допустимыми базовыми типами являются
все порядковые типы.
28 Lower bound greater than upper
bound (Нижняя граница больше верхней).
Описание типа-диапазона содержит
неправильные границы.
29 Ordinal type expected (Нужен
порядковый тип) .
Вещественные, строковые, структурные,
процедурные типы и указатели в данном
месте программы не допускаются.
30 Integer constant expected
(Нужна целая константа).
31 Constant expected (Нужна
константа).
32 Integer or real constant
expected (Нужна целая или вещественная
константа) .
33 Tуре identifier expected
(Нужен идентификатор типа)
34 Invalid function result type
(Неправильный тип результата функции)
Правильными типами результата функции
являются все простые типы, строковые
типы и указатели.
35 Label identifier expected
(Нужен идентификатор метки).
Метка не обозначена с помощью
идентификатора, как это требуется из
контекста программы.
36 BEGIN expected (Нужен
BEGIN).
37 END expected (Нужен END).
38 Integer expression expected
(Нужно выражение типа INTEGER).
39 Ordinal expression expected
(Нужно выражение перечисляемого типа).
40 Boolean expression expected
(Нужно выражение типа BOOLEAN).
41 Operand types do not match
operator (Типы операндов не соответствуют
операции).
Данная операция не может быть применена
к указанным операндам, например, ‘ А’ div
‘ 2 ‘ .
42 Error in expression (Ошибка
в выражении).
Данный символ не может участвовать в
выражении указанным образом. Возможно,
Вы забыли указать операцию между двумя
операндами.
43 Illegal assignment (Неверное
присваивание).
Файлам и нетипизированным переменным
нельзя присваивать значения. Идентификатору
функции можно присвоить значение только
внутри раздела операторов данной
функции.
44 Field identifier expected
(Нужен идентификатор поля).
Попытка использовать запись целиком в
том месте, где требуется ссылка на
какое-либо поле записи.
45 Object file too large
(Объектный файл слишком большой).
Турбо Паскаль не может компоновать
файлы .OBJ больше 64 Кбайт.
46 Undefined external
(Неопределенная внешняя процедура).
Внешняя процедура или функция не имеет
соответствующего определения PUBLIC в
объектном файле. Убедитесь, что Вы
указали все объектные файлы в директивах
{$L <имя .OBJ-файлa>} и проверьте написание
идентификаторов процедуры или функции
в файле . ASM.
47 Invalid object file record
(Неправильная запись объектного файла).
Файл .OBJ содержит неверную объектную
запись. Убедитесь, что данный файл
является действительно файлом .OBJ.
48 Code segment too large
(Сегмент кода слишком большой).
Максимальный размер кода программы или
программного модуля равняется 65520
байтам. Разбейте Вашу программу или
модуль на два или более модулей.
49 Data segment too large
(Сегмент данных слишком велик).
Максимальный размер сегмента данных
программы равен 65520 байтам, включая
данные, используемые программными
модулями. Если Вам нужно большее
количество глобальных данных, опишите
большие структуры с помощью указателей
и выделяйте для них память динамически
с помощью процедуры NEW.
50 DO expected (Нужен
оператор DO).
51 Invalid PUBLIC definition
(Неверное PUBLIC-определение).
Возможные причины сообщения:
-
данный идентификатор получил тип PUBLIC
с помощью соответствующей директивы
языка ассемблера, но не соответствует
описанию EXTERNAL в программе или программном
модуле Паскаля; -
две или более директивы PUBLIC языка
ассемблера определяют один и тот же
идентификатор; -
файлы .OBJ определяют символы PUBLIC, не
находящиеся в сегменте CODE.
52 Invalid EXTRN definition
(Неправильное EXTRN-определение).
Возможные причины сообщения:
-
программа на ассемблере ссылается с
помощью директивы EXTRN на идентификатор,
который не описан в программе на Паскале
и не был описан в интерфейсных секциях
используемых программных модулей; -
ассемблерная программа ссылается на
идентификатор, обозначающий абсолютную
переменную (т.е. определенную словом
ABSOLUTE); -
ассемблерная программа ссылается на
идентификатор процедуры или функции
типа INLINE.
53 Too many EXTRN definition
(Слишком много EXTRN-определений).
Турбо Паскаль не может обрабатывать
файлы .OBJпри более чем 256 определениях
EXTRN.
54 OF expected (Требуется
OF).
55 INTERFACE expected (Требуется
интерфейсная секция).
56 Invalid relocatable reference
(Неправильная перемещаемая ссылка).
Возможные причины сообщения:
-
файл .OBJ содержит данные и перемещаемые
ссылки в сегментах, отличных от CODE.
Например, Вы пытаетесь описать
инициализированные переменные в
сегменте DATA; -
файл .OBJ содержит ссылки с размерами в
байтах на перемещаемые символы. Такая
ошибка происходит в случае, если Вы
используете операторы HIGH и LOW с
перемещаемыми символами или если Вы
ссылаетесь в директивах DB на перемещаемые
символы; -
операнд ссылается на перемещаемый
символ, который не был определен в
сегменте CODE или в сегменте DATA; -
операнд ссылается на процедуру EXTRN или
функцию EXTRN со сдвигом, например, CALL
SortProc+8.
57 THEN expected (Требуется
THEN).
58 TO or DOWNTO expected
(Требуется ТО или DOWNTO).
59 Undefined forward
(Неопределенное опережающее описание).
Возможные причины сообщения:
-
была рписана процедура или функция в
интерфейсной секции программного
модуля, но ее определение отсутствует
в секции реализации; -
процедуры или функции были описаны с
помощью опережающего описания, но их
определение не найдено.
60 Too many procedures (Слишком
иного процедур).
Турбо Паскаль допускает не более 512
процедур или функций в одном модуле.
Если Вы компилируете программу, то
поместите некоторые процедуры или
функции в модули. Если Вы компилируете
модуль, то разбейте его на два или
несколько модулей.
61 Invalid typecast (Неверное
преобразование типа).
Возможные причины сообщения:
-
Вы пытаетесь разместить в памяти,
занимаемой некоторой переменной,
значение выражения другого типа э
случае, когда размер размещаемого
значения не равен размеру переменной; -
Вы пытаетесь осуществить преобразование
типа выражения, когда разрешается
только ссылка на переменную, процедуру
или функцию.
62 Division by zero (Деление
на ноль).
Предшествующая операция пытается
выполнить деление на ноль.
63 Invalid file type (Неверный
файловый тип).
Данный файловый тип не обслуживается
процедурой обработки файлов. Например,
процедура READLN используется для
типизированного файла или процедура
SEEK — для текстового файла.
64 Cannot Read or Write variables
of this type (Нет возможности считать или
записать переменные данного типа).
Нарушены следующие ограничения:
-
процедуры READ и READLN могут считывать
переменные символьного, целого,
действительного и строкового типов; -
процедуры WRITE и WRITELN могут выводить
переменные символьного, целого,
действительного, булевского и строкового
типов.
65 Pointer variable expected
(Нужно использовать переменную-указатель).
Предыдущая переменная должна быть
указателем.
66 String variable expected
(‘Нужна строковая переменная) .
Предшествующая переменная должна иметь
строковый тип.
67 String expression expected
(Нужно выражение строкового типа).
Предшествущее выражение должно иметь
строковый тип.
68 Circular unit reference
(Перекрестная ссылка модулей).
Два модуля ссылаются друг на друга:
Unit A;
Unit В;
Uses В;
Uses А;
…..
…..
69 Unit name mismatch
(Несоответствие имен программных
модулей).
Имя программного модуля, найденное в
файле .TPU, не соответствует имени,
указанному в предложении USES.
70 Unit version mismatch
(Несоответствие версий модулей).
Один или несколько программных модулей,
используемых данной программой, были
изменены после их компиляции. Воспользуйтесь
опцией COMPILE/MAKE или COMPILE/BUILD в интегрированной
среде или опциями /М или /В в компиляторе
ТРС, что позволит автоматически
скомпилировать программные модули,
нуждающиеся в перекомпиляции.
71 Duplicate unit name (Повторное
имя программного модуля).
Вы уже указали этот программный модуль
в операторе USES.
72 Unit file format error (Ошибка
формата файла модуля).
Файл .TPU не соответствует стандарту
Турбо Паскаля.
73 IMPLEMENTATION expected
(Отсутствует исполняемая часть модуля).
74 Constant and case types do not
match (Типы констант и тип выражения
оператора CASE не соответствуют друг
другу).
Тип константы оператора CASE не совместим
с выражением в операторе варианта.
75 Record variable expected
(Нужна переменная типа запись) .
Предшествующая переменная должна иметь
тип запись.
76 Constant out of range
(Константа нарушает границы).
Возможные причины сообщения:
-
Вы пытаетесь указать индекс массива,
выходящий за его границы; -
Вы пытаетесь присвоить переменной
значение, выходящее за границы, допустимые
для типа этой переменной; -
Вы пытаетесь передать в качестве
фактического параметра процедуре или
функции константу, выходящую за границы,
допустимые для типа соответствующего
формального параметра.
77 File variable expected (Нужна
файловая переменная).
Предшествующая переменная должна иметь
файловый тип.
78 Pointer expression expected
(Нужно выражение типа указатель).
Предшествующее выражение должно иметь
тип указателя.
79 Integer or real expression
expected (Нужно выражение вещественного
или целого типа).
Предшествующее выражение должно иметь
тип REAL или INTEGER.
80 Label not within current block
(Метка не находится внутри текущего
блока) .
Оператор GOTO не может ссылаться на метку,
находящуюся вне текущего блока.
81 Label already defined (Метка
уже определена).
Данная метка уже помечает оператор.
82 Undefined label in processing
statement part (Неопределенная метка в
предшествующем разделе операторов).
Данная метка была описана, и на нее
осуществлялась ссылка в предшествующем
разделе операторов, но она не указана
в тексте программы.
83 Invalid @ argument
(Неправильный аргумент операции @).
Правильными аргументами являются
идентификаторы переменных, процедур и
функций.
84 Unit expected (Нужно
кодовое слово UNIT).
85«;» expected (Нужно
указать»;») .
86«:» expected (Нужно
указать*:») .
87«,» expected (Нужно
указать»,») .
88 «(» expected (Нужно
указать «(»).
89«)» expected (Нужно
указать»)»).
90 «=» expected (Нужно
указать «=») .
91«:=» expected (Нужно
указать»:=»).
92 «[» or «(.» expected
(Нужно указать «[» или «(.»).
93«]» or «.)» expected (Нужно
указать»]» или».)»).
94».» expected (Нужно
указать».») ,
95«..» expected (Нужно
указать»..») .
96 Too many variables (Слишком
много переменных).
Нарушены следующие ограничения:
-
общий размер глобальных переменных,
описанных в программе или программном
модуле, не может превышать 64 Кбайт; -
размер локальных переменных, описанных
в процедуре или функции, не может
превышать 64 Кбайт. .
97 Invalid FOR control
variable(Неправильный параметр цикла
оператора FOR).
Параметр цикла оператора FOR должен быть
переменной порядкового типа, определенной
в разделе описаний текущей подпрограммы.
98 Integer variable expected
(Нужна переменная целого типа).
Предшествующая переменная должна иметь
целый тип.
99 File and procedure types are
not allowed here (Здесь не могут использоваться
файлы или процедурные типы).
Типизированная константа не может иметь
файловый или процедурный тип.
100 String length mismatch
(Несоответствие длины строки).
Длина строковой константы не соответствует
количеству элементов символьного
массива.
101 Invalid ordering of fields
(Неверный порядок полей).
Поля в константе типа запись должны
записываться в порядке их описания.
102 String constant expected
(Нужна константа строкового типа).
103 Integer or real variable
expected (Нужна переменная типа INTEGER или
REAL).
Предшествующая переменная должна иметь
целый или вещественный тип.
104 Ordinal variable expected
(Нужна переменная порядкового типа).
Предшествующая переменная должна иметь
порядковый тип.
105 INLINE error (Ошибка в
операторе INLINE).
Оператор «<» не допускается в сочетании
с перемещаемыми ссылками на переменные.
Такие ссылки всегда имеют размер в
слово.
106 Character expression expected
(Предшествующее выражение должно иметь
символьный тип).
107 Too many relocation items
(Слишком много перемещаемых Элементов).
Размер таблицы перемещения файла .ЕХЕ
превышает 64 Кбайта, что является верхним
пределом в Турбо Паскале. Если Вы
обнаружили эту ошибку, то это значит,
что программа просто слишком велика
для обработки компоновщиком Турбо
Паскаля. Возможно также, что она слишком
велика для выполнения в MS-DOS. В таком
случае нужно выделить в программе
основной раздел, который выполнял бы
обращение к двум или более вспомогательным
разделам с помощью процедуры ЕХЕС из
модуля DOS (см. гл.11).
108 Overflow in arithmetic
operator (Переполнение при выполнении
арифметического оператора).
Результат предыдущей арифметической
операции не лежит в диапазоне -2 146 483
648…+2 147 483 647. Исправьте операцию или
используйте вещественные типы вместо
целочисленных.
109 No enclosing FOR, WHILE or
REPEAT statment (Нет операторов, заканчивающих
операторы FOR, WHILE или REPEAT) .
Процедуры BREAK и CONTINUE не могут вызываться
вне тела оператора цикла.
110 Debug information table
overflow (Переполнение информационной
таблицы отладки).
Возможно, программа содержит более
65536 имен или 65536 строк. Отключите генерацию
таблиц отладки директивой компилятора
{$D-} или исправьте один или более модулей.
111
Ошибка с этим кодом не описана в версии
7.0 системы Турбо Паскаль.
112 CASE constant out of
range(Константа CASE нарушает допустимые
границы).
Целочисленные константы оператора CASE
должны находиться в диапазоне от -32768
до 32767.
113 Error in
statement (Ошибка
в
операторе).
Данный символ не может быть первым
символом в операторе.
114 Cannot call an interrupt
procedure (Невозможно вызвать процедуру
прерывания) .
Вы не можете непосредственно вызвать
процедуру обработки прерывания.
115
Ошибка с этим кодом не описана в версии
7.0 системы Турбо Паскаль.
116 Must be in
8087 mode to compile this (Для
компиляции
необходим
режим
8087) .
Данная программа может быть скомпилирована
только в режиме {$N+}. В состоянии {SN-}
операции с типами SINGLE, DOUBLE, EXTENDED и СОМР
не допускаются.
117 Target address not found
(Указанный адрес не найден).
Команда COMPILE/FIND ERROR в среде Турбо Паскаля
(или поиск с помощью опции /F в командной
строке компилятора ТРС.ЕХЕ) не обнаружила
оператор, соответствующий заданному
адресу.
118 Include
files are not allowed here (Здесь
не
допускаются
включаемые
файлы)
.
Раздел операторов должен целиком
размещаться в одном файле.
119 No inherited methods are
accessible here (В этом месте программы нет
унаследованных методов).
Вы используете зарезервированное слово
INHERITED вне метода объекта или в методе,
который не унаследован от родительского
объекта.
120
Ошибка с этим кодом не описана в версии
7.0 системы Турбо Паскаль. .
121 Invalid qualifier (Неверный
квалификатор).
Возможные причины сообщения:
-
Вы пытаетесь индексировать переменную,
которая не является массивом; -
Вы пытаетесь указать поля в переменной,
которая не является записью; -
Вы используете в качестве указателя
переменную, которая не является
указателем.
122 Invalid variable reference
(Недействительная ссылка на переменную).
Предыдущая конструкция удовлетворяет
синтаксису ссылки на переменную, но она
не указывает адрес памяти. Возможно Вы
вызываете функцию-указатель, но забываете
сослаться на результат с помощью знака
^.
123 Too many symbols'(Слишком
много символов) .
Программа или программный модуль
содержат более 64 Кбайт символов. Если
Вы компилируете программу с директивой
{$D+}, то попробуйте отключить эту директиву
или разбейте программу на несколько
модулей.
124 Statement part too large
(Слишком большой раздел операторов).
Турбо Паскаль ограничивает размер
раздела операторов до величины примерно
24 Кбайта. Если Вы обнаружили эту ошибку,
поместите части раздела операторов в
одну или несколько процедур и вообще
сделайте Вашу программу более
структурированной.
125
Ошибка с этим кодом не описана в версии
7.0 системы Турбо Паскаль.
126 Files must be var parameters
(Файлы должны передаваться как
параметры-переменные) .
Вы пытаетесь передать процедуре или
функции параметр-значение файлового
типа. Параметры файлового типа должны
быть параметрами-переменными.
127 Too many conditional symbols
(Слишком много условных символов).
Недостаточно памяти для определения
условных символов (слов, управляющих
командами условной компиляции).
Попытайтесь удалить некоторые символы
или уменьшить их длину.
128 Misplaced conditional
directive (Пропущена условная директива).
Компилятор обнаружил директиву {$ELSE}
или {$ENDIF} без соответствующих директив
{$IFDEF}, {$IFNDEF} или {$IFOPT}.
129 ENDIF
directive missing (Пропущена
директива
ENDIF).
Исходный файл закончился внутри
конструкции условной компиляции. В
исходном файле должно быть равное
количество директив {$IFxxx} и {$ENDIF}.
130 Error in
initial conditional defines (Ошибка
в
условных
определениях).
Исходные условные символы.указанные в
опции OPTIONS/COMPILER /CONDITIONAL DEFINES являются
недействительными. Турбо Паскаль требует
нуля или более идентификаторов,
разделенных пробелами, запятыми или
точками с запятой.
131 Header does not match
previous definition (Заголовок не соответствует
предыдущему определению).
Возможные причины сообщения:
-
заголовок процедуры или функции,
указанный в интерфейсной секции, не
соответствует заголовку в исполняемой
части. -
заголовок процедуры или функции,
указанный с помощью опережающего
описания FORWARD, не соответствует заголовку
найденной далее одноименной процедуры
или функции.
132 Critical disk error
(Критическая ошибка диска).
Во время компиляции произошла критическая
ошибка диска (например, дисковод находится
в состоянии «не готов»).
133 Cannot
evaluate this expression (Нельзя
вычислить
данное
выражение).
В выражении-константе или в отладочном
выражении Вы пытаетесь использовать
неподдерживаемые средства, например,
в описании константы пытаетесь
использовать функцию SIN или вызвать в
отладочном выражении определенную
пользователем функцию.
134 Expression incorrectly
terminated (Некорректное завершение
выражения).
Контекстуально в данном месте программы
должен быть конец выражения или оператора.
135 Invalid format specifier
(Неверный спецификатор формата).
Используется неверный спецификатор
формата или числовой аргумент спецификатора
формата выходит за допустимые границы.
136 Invalid indirect reference
(Недопустимая косвенная ссылка).
Оператор пытается осуществить недопустимую
косвенную ссылку. Например, Вы используете
абсолютную переменную, базовая переменная
которой в текущем модуле неизвестна,
или используете программу типа INLINE, в
которой делается ссылка на переменную,
неопределенную в текущем модуле.
137 Structured variable are not
allowed here (Здесь нельзя использовать
переменную структурного типа).
Делается попытка выполнить над переменной
структурного типа неподдерживаемую
операцию. Например, Вы пытаетесь
перемножить две записи.
138 Cannot evaluate without
System unit (Нельзя вычислить выражение без
модуля SYSTEM).
Чтобы отладчик смог вычислить выражение,
в файле TURBO.TPL должен содержаться модуль
SYSTEM.
139 Cannot access this symbol
(Нет доступа к данному символу).
Как только Вы скомпилируете программу,
все множество ее символов становится
доступным. Однако к отдельным символам
(например, к переменным) нельзя получить
доступ, пока Вы не запустите программу.
140 Invalid floating-point
operation (Недопустимая операция с плавающей
запятой) .
При выполнении операции с плавающей
запятой произошло переполнение или
деление на ноль.
141 Cannot compile overlay to
memory (Нельзя выполнить компиляцию
оверлейных модулей в память).
Программа, использующая оверлейные
модули, должна компилироваться на диск.
142 Procedure or function
variable expected (Должна использоваться
переменная процедурного типа).
В этом контексте оператор получения
адреса @ может использоваться только с
переменной процедурного типа.
143 Invalid
procedure or function reference (Недопустимая
ссылка
на
процедуру
или
функцию).
Возможные причины сообщения:
-
Вы пытаетесь вызвать процедуру в
выражении; -
процедура или функция, использующаяся
в качестве параметра вызова другой
процедуры или функции, должна
компилироваться в состоянии {$F+} и не
может описываться с помощью
зарезервированных слов INLINE или INTERRUPT.
144 Cannot overlay this unit
(Этот модуль не может использоваться в
качестве оверлейного).
Попытка использовать в качестве
оверлейного модуль, который не был
скомпилирован с директивой {$O+}.
145 Too many nested scopes
(Слишком много вложений).
В программе не может быть больше 512
вложений с не более чем 128 вложениями в
каждом модуле. Вложениями считаются:
-
каждый модуль в предложении USES;
-
каждая вложенная запись в типе RECORD;
-
каждый вложенный оператор WITH.
146 File access denied (Отказано
в доступе к файлу).
Возможные причины:
-
Вы пытаетесь использовать файл с
атрибутом «только для чтения» в качестве
выводного файла; -
Вы используете имя каталога вместо
имени выводного файла.
147 Object
type expected (Здесь
должен
быть
тип
OBJECT).
Приложения написанные на Free Pascal могут генерировать ошибку времени выполнения (Run Time Error) когда в программе обнаруживаются определённые аварийные состояния . Этот документ содержит список возможных ошибок и описание их возможных причин.
1 Invalid function number (Неправильный номер функции)
Была попытка неправильного вызова системной функции.
2 File not found (Файл не найден)
Генерируется при попытке перенаименования, стирания или открытия несуществующего файла.
3 Path not found (Путь(директория) не найден)
Генерируется файловой системой когда путь не существует или неправелен.
Также генерируется при попытке получить доступ к несуществующему файлу.
4 Too many open files (Слишком много файлов открыто)
Максимальное число открытых файлов для вашего процесса было превышено.
Большинство операционных систем ограничивают максимальное число открытых файлов,
и эта ошибка может возникнуть когда этот лимит превышен.
5 File access denied (В доступе к файлу — отказано)
Было запрешено получение доступа к файлу. Эта ошибка может произойти по нескольким причинам:
-
При попытке открыть файл, предназначенный только для чтения или в деиствительности являющиёся директорией, для записи.
-
В данный момент занят или заблокирован другим процессом.
-
При попытке создания файла или директории с именем, которое совпадает с именем уже созданного файла или директории.
-
При попытке чтения из файла, открытого только для записи.
-
При попытке записи в файл, открытый только для чтения.
-
При попытке удалить директорию или файл, когда это не возможно.
-
При неимении прав на доступ к данному файлу.
6 Invalid file handle (Неправильный хэндл файла)
Происходит, когда используемая Вами файловая переменная была обнулена (испорчена); Это говорит о том, что память вашей программы была повреждена.
12 Invalid file access code (Неправильные ключи доступа к файлу)
Генерируется когда процедуры reset или rewrite вызываются с неправильным параметром FileMode.
15 Invalid drive number (Неправильный номер диска)
Генерируется когда в функции Getdir или ChDir был передан неправильный номер диска.
16 Cannot remove current directory (Невозможно удалить текущую директорию)
Генерируется при попытке удалить текущую директорию.
17 Cannot rename across drives (Можно переименовывать файлы только в пределах одного диска)
Вы не можете переименовать файл в файл, находяшиёся на другом диске или в другом разделе.
100 Disk read error (Ошибка чтения с диска)
Генерируется при невозможности произвести чтение с диска. Обычно происходит при попытке чтения данных, после его окончания.
101 Disk write error (Ошибка записи на диск)
Генерируется когда Вы пытаетесь записать данные на переполненый диск.
102 File not assigned (Файл не определён)
Генерируется функциями Reset, Rewrite, Append, Rename и Erase, При передаче в них файловой переменной, для которой не была выполнена функция AssignFile.
103 File not open (Файл не открыт)
Генерируется следующими функциями : Close, Read, Write, Seek, EOf, FilePos, FileSize, Flush, BlockRead, и BlockWrite если файл не был открыт.
104 File not open for input (Файл не открыт для чтения)
Генерируется функциями Read, BlockRead, Eof, Eoln, SeekEof и SeekEoln если файл не был открыт при помощи Reset.
105 File not open for output (Файл не открыт для записи)
Генерируется функцией write если текстовый файл не был открыт при помощи Rewrite.
106 Invalid numeric format(Неправильный числовой формат)
Генерируется когда ожидалось числовое значение, но из текстого файла было прочитано не было.
150 Disk is write-protected (Диск защищён от записи)
(Критическая ошибка)
151 Bad drive request struct length (Неправильная длина структуры запроса)
(Критическая ошибка)
152 Drive not ready (Устройство не готово)
(Критическая ошибка)
154 CRC error in data (Ошибка контрольной суммы в данных)
(Критическая ошибка)
156 Disk seek error (Ошибка низкоуровнего поиска на диске)
(Критическая ошибка)
157 Unknown media type (Неизвестный тип …)
(Критическая ошибка)
158 Sector Not Found (Сектор не найден)
(Критическая ошибка)
159 Printer out of paper (Нет бумаги в принтере)
(Критическая ошибка)
160 Device write fault (Сбой записи устройства)
(Критическая ошибка)
161 Device read fault (Сбой чтения устройства)
(Критическая ошибка)
162 Hardware failure (Сбой железа)
(Критическая ошибка)
200 Division by zero (Деление на ноль)
Приложение пыталось разделить число на ноль.
201 Range check error (Ошибка проверки границ)
Если вы компилировали прогамму с включённой провереой границ, Вы можете получить эту ошибку в следующих случаях:
-
Массив был вызван с индексом, выходящим за декларированые пределы.
-
Попытка присвоить значение переменной, выходящее за декларированые границы (для instance и enumerated типов).
202 Stack overflow error (Переполнение стека)
Стек превысил свой максимально допустимый размер (в этом случае необходимо уменьшить размер локальных переменных), или стек был повреждён. Эта ошибка генерируется только с включённой проверкой стека.
203 Heap overflow error (Переполнение кучи)
Размер кучи превысил максимально возможный размер. Генерируется при попытке выделить память непосредственно функциями New, GetMem и ReallocMem, или когда экземпляр класса или объекта создаётся и памяти не достаточно. Пожалуйста учтите что, по умолчанию, Free Pascal поддерживает увеличение кучи, то есть, если необходимо, будет произведена попытка её увеличения. Как бы то ни было, если размер кучи превысил максимально допустимый системой и
железом, то Вы получите эту ошибку.
204 Invalid pointer operation (Непрваильная операция с указателем)
Будет сгенерирована при вызове функций Dispose или Freemem с неправильным указателем (чаще всего, Nil)
205 Floating point overflow (Максимальная границы числа с плавающей точкой)
Вы попытались использовать или создать слишком большое число с плавающей точкой.
206 Floating point underflow (Минимальная граница числа с плавающей точкой)
Вы попытались использовать или создать слишком маленькое число с плавающей точкой.
207 Invalid floating point operation (Неправильная операция над числами с плавающей точкой)
Может генерироваться если вы попытались получить квадратный корень или логарифм отрицательного числа.
210 Object not initialized (Объект не инициализирован)
Если программа была скомпилирована с включенной проверкой границ, эта ошибка будет сгенерирована при попытке вызвать виртуальный метод до его конструктора.
211 Call to abstract method (Попытка вызова абстрактного метода)
Ваша программа попыталась вызвать абстрактный виртуальный метод. Абстрактные методы должны быть перекрыты, и только перекрытый метод должен быть вызван.
212 Stream registration error (Ошибка регистрации потока)
Генерируется когда неправильный тип регистрируется в модуле objects.
213 Collection index out of range (Индекс элемента коллекции выходит за допустимые границы)
Генерируется когда Вы попытались обратиться к элементу коллекции с выходящим за допустимые границы индексом (модуль objects).
214 Collection overflow error (Переполнение коллекции)
Размер коллекции превысил максимально допустимый размер, а Вы попытались добавить новый элемент (модуль objects).
215 Arithmetic overflow error (Арифметическое переполнение)
Эта ошибка генерируется когда результат операции превысил допустимые границы. В отличие to Turbo Pascal, эта ошибка генерируется только для 32-bit и 64-bit арифметических переполнений. Это происходит согласно тому, что все операнды конвертируются в 32-bit или 64-bit, до того как производить вычисления.
216 General Protection fault (GP Ошибка защиты памяти)
Приложение попыталось обратиться к недопустимому участку памяти. Это может быть вызвано следующими причинами:
-
Попытка получить разуказатель для nil.
-
Попытка получить доступ к выходящему за допустимые границы участку памяти (например, вызов move с неправильной длиной).
217 Unhandled exception occurred (Произошо неизвестное исключение)
Произошло исключение, и для него не существеет хэндла. Модуль sysutils устанавливает handler(менеджер), который отлавливает все исключения, и безопасно выходит в случае обнаружения оного.
219 Invalid typecast (Неправильное приведение типов)
Генерируется когда недопустимое приведение типов производится над классом используя оператор as. Эта ошибка также генерируется, когда объект или класс приводится к недопустимому объекту или классу, и виртуальный метод этого объекта или класса вызывается. Эта последняя ошибка детектируется только с использованием опции -CR компилятора.
227 Assertion failed error (Сбой утверждения)
Утверждение провалено, и процедурная переменная AssertErrorProc не была уcтановлена.
Содержание
Отладка программ в Turbo Pascal
Автор: volvo877 (он же и volvo71)
Ссылка на оригинал статьи
(не хватает картинок из статьи)
Каждый программист знает, что программу надо не только написать, иначе говоря —
«заставить работать», а еще и отладить, т.е. заставить ее работать правильно…
Для того, чтобы делать это быстро и эффективно, желательно научиться
пользоваться встроенными в IDE средствами отладки программ…
Интегрированная интерактивная среда разработки программ Borland Pascal (IDE)
включает в себя ряд средств, облегчающих разработку программ: автоматическое
управление проектами, средств обеспечения модульной структуры программы,
быструю компиляцию и простые в использовании оверлеи. Но, несмотря на все это,
Ваша программа все равно может содержать ошибки, что не позволит ей корректно
работать.
IDE для DOS Borland Pascal предоставляет вам инструментальные средства для
отладки программ, то есть поиска и исправления ошибок. В этой статье
описываются инструментальные средства и процедуры отладки программы в
интегрированной среде Борланд Паскаль (большинство описанных возможностей
применимо также к IDE FreePascal-я).
Что такое отладка?
Отладка — это процесс поиска и исправления ошибок в программе, препятствующих
корректной работе программы. Перед тем как углубиться в специфические средства
IDE, которые помогают при отладке, дадим краткое описание видов ошибок, которые
Вы можете наблюдать, и различного рода операций, которые будут использоваться
для их поиска.
Какие существуют виды ошибок?
Существует три основных типа ошибок:
-
Ошибки этапа компиляции
-
Ошибки этапа выполнения
-
Логические ошибки
Ошибки этапа компиляции
Ошибки этапа компиляции или синтаксические ошибки происходят, когда
исходный код программы нарушает правила синтаксиса Паскаля. Компилятор не
может скомпилировать программу, пока она не будет содержать только
допустимые операторы Паскаля. Когда компилятор встречает оператор, который он не может распознать, соответствующий файл выводится в окне
редактирования, курсор устанавливается на то место, которое не понял
компилятор, и выводится сообщение об ошибке.
Наиболее общей причиной ошибок этапа компиляции являются ошибки набора (опечатки), пропущенные точки с запятой, ссылки на неописанные переменные, передача неверного числа (или типа) параметров процедуры или функции и присваивание переменной значения неверного типа.
После исправления ошибки компиляцию необходимо выполнить заново. После устранения в программе всех синтаксических ошибок и ее успешной компиляции программа будет готова к выполнению и поиску ошибок этапа выполнения и логических ошибок.
Ошибки этапа выполнения
Ошибки этапа выполнения или семантические ошибки происходят, когда вы
запускаете успешно откомпилированную программу, которая при выполнении
делает что-то недопустимое. То есть, программа содержит допустимые
операторы Паскаля, но при выполнении этих операторов что-то происходит
неверно. Например, программа может пытаться открыть для ввода
несуществующий файл или выполнить деление на ноль.
Когда такая ошибка обнаруживается, выполнение программы завершается, и выводится сообщение следующего вида:
Run-time error ## at seg:ofs
Если Вы выполняете программу из IDE, она автоматически находит оператор,
вызвавший ошибку (как и в случае синтаксических ошибок). Если же программа выполняется вне IDE (EXE-файл запускается из командной строки или файлового менеджера ОС), то вы можете запустить IDE и, чтобы найти вызвавший ошибку оператор, использовать команду Search → Find Error, которая дает вам адрес сегмента и смещения (seg:ofs).
Логические ошибки
Логические ошибки — это ошибки проектирования и реализации программы. То
есть, операторы, используемые в программе, допустимы, и что-то делают, но
не то, что Вы предполагали. Эти ошибки часто трудно отследить, поскольку
IDE не может найти их автоматически, как синтаксические и семантические
ошибки. К счастью, IDE включает в себя также и средства отладки, помогающие вам найти логические ошибки.
Логические ошибки приводят к некорректному или непредвиденному изменению значений переменных, неправильному отображению графики или невыполнению кода тогда, когда это ожидается. В остальной части этой статьи обсуждаются методы отслеживания логических ошибок.
Иногда, когда программа делает что-то непредвиденное, причина достаточно очевидна, и Вы можете быстро исправить код программы. Но другие ошибки более трудноуловимы и вызываются в результате взаимодействия различных частей программы. В этих случаях лучше всего остановить вашу программу в заданной точке, пройти ее шаг за шагом и просмотреть состояние переменных и выражений.
Пошаговый прогон: какая разница между F4, F7 и F8?
Основной смысл использования встроенного отладчика состоит в управляемом
выполнении. Отслеживая выполнение каждой инструкции, Вы можете легко
определить, какая часть Вашей программы вызывает проблемы. В отладчике
предусмотрено пять основных механизмов управления выполнением программы,
которые позволяют вам:
-
Выполнять инструкции по шагам
-
Трассировать инструкции
-
Выполнять программу до заданной точки
-
Находить определенную точку
-
Выполнять сброс программы
Само по себе выполнение программы по шагам может быть недостаточно полезным, разве что поможет найти то место, где что-то происходит совершенно неверно. Но управляемое выполнение дает Вам возможность проверять состояние программы и ее данных, например, отслеживать вывод программы и ее переменные.
Что такое шаг?
Когда Вы отлаживаете программу, наименьшим выполняемым элементом является
строка. Это означает, что Вы можете управлять отладкой до уровня отдельной строки исходного кода программы. Поэтому, если на одной строке программы содержится несколько операторов Паскаля, эти операторы не могут быть отлажены индивидуально. С другой стороны, с целью отладки оператор можно разбить на несколько строк, каждая из которых будет выполняться за один шаг.
Все выполнение в отладчике, включая выполнение по шагам, трассировку и останов, основывается на строках. Подсвечивая строку, встроенный отладчик всегда сообщает Вам, какую строку он выполнит на следующем шаге (строка выполнения). Строка выполнения выводится цветом, отличным от нормального цвета. Благодаря этому Вы можете легко видеть, где находитесь.
Выполнение программы по шагам
Выполнение по шагам — это простейший способ выполнения программы по
элементарным фрагментам. Выбор команды Run → Step Over или нажатие клавиши F8 вызывает выполнение отладчиком всего кода в операторе, указанном строкой выполнения, включая любые вызываемые на ней процедуры или функции, пока управление не вернется обратно к вам. После этого строка выполнения указывает следующий выполняемый оператор.
Возьмем, например, следующую программу:
program StepTest; function Negate(X: Integer): Integer; begin Negate := -X; end; var I: Integer; begin for I := 1 to 10 do Writeln(Negate(I)); end.
Если в окне редактирования Вы выведете StepTest и нажмете клавишу F8, то строка выполнения перемещается на оператор begin в начале основного цикла, поскольку это первое, что выполняется в программе. Второе нажатие клавиши F8 выполняет begin и перемещает строку выполнения вниз до оператора for на следующей строке.
После этого нажатие F8 вызывает выполнение всего цикла for; на экран
пользователя выводятся числа от -1 до -10, а строка выполнения перемещается к end.
Хотя функция Negate и вызывается 10 раз, строка выполнения никогда на нее не перемещается. Выполнение по шагам позволяет отладчику не показывать детали любых вызовов для отдельной строки. Выполнение по шагам вызывает выполнение всего цикла for сразу, поэтому Вы не сможете видеть изменения в ходе выполнения цикла. Если же Вы хотите видеть подробности выполнения цикла, внесите в пример следующее простое изменение.
begin for I := 1 to 10 do WriteLn(Negate(I)); end.
Поскольку оператор Паскаля может занимать несколько строк, такая программа будет в точности эквивалентна предыдущей версии, и генерируемый код будет идентичен. Но поскольку оператор WriteLn теперь находится на отдельной строке, отладчик может интерпретировать его отдельно. Если теперь Вы будете нажимать клавишу F8, то увидите, что строка выполнения будет при выполнении цикла 10 раз возвращаться на WriteLn.
Трассировка программы
Трассировка программы во многом аналогична ее выполнению по шагам. Единственное исключение состоит в том, что когда встречается оператор вызова процедуры/функции, при трассировке эти процедуры и функции также выполняются по шагам, а при простом выполнении по шагам управление возвращается вам после завершения выполнения подпрограммы.
Например, чтобы выполнить трассировку кода в вышеприведенном примере, загрузите файл, затем выберите команду Run → Trace Into или нажмите клавишу F7. Когда Вы в первый раз делаете это, управление перемещается на оператор begin основной программы. Повторное нажатие F7 снова перемещает строку управления на оператор for. После этого нажатие клавиши F7 трассирует вызов функции Negate — строка выполнения перемещается на оператор begin в блоке функции. Если Вы продолжаете нажимать F7, строка выполнения перемещается по функции, а затем, когда Вы дойдете до оператора end, возвращается к оператору вызова.
Формат программы влияет на поведение строки выполнения при трассировке, хотя и не в такой степени как при пошаговом выполнении. Если код сформатирован как в первоначальном варианте приведенного выше примера, то трассировка оператора for приводит к выполнению 10 раз функции Negate. Если вы разобьете оператор for на две строки, то трассировка оператора end функции возвращает строку выполнения: ту строку основной программы, которая будет выполняться следующей. Первые девять раз это снова будет вызов функции. В десятый раз строка выполнения перемещается на оператор end программы.
Трассировка или выполнение по шагам?
Пошаговое выполнение и трассировка выполняют одно и то же действие, кроме того случая, когда строка выполнения находится на строке вызова процедуры/функции, или когда выполняется оператор begin в начале программы или модуля, который использует другие модули.
Выполнение begin в блоке begin..end основной программы вызывает код
инициализации для любого используемого в программе модуля в том порядке,
который указывается в операторе uses программы. Аналогично, выполнение
оператора begin в начале секции инициализации вызывает код инициализации для любых модулей, используемых в данном модуле. Выполнение по шагам и трассировка работает в этих случаях как и следовало ожидать — пошаговое выполнение begin выполняет всю инициализацию, возвращая управление на следующий оператор только после того, как все будет завершено; при трассировке выполняется трассировка кода инициализации.
Пошаговое выполнение и трассировка методов объектов
Если в программе используются объекты, отладчик ведет себя аналогично своему поведению в случае обычных процедур/функций. Пошаговое выполнение метода интерпретирует метод как один шаг, возвращая управление к отладчику после того как метод завершает выполнение. Трассировка метода загружает и выводит на экран код метода и трассирует его операторы.
Выполнение больших фрагментов
Иногда, конечно, нежелательно выполнять по шагам всю программу только для того, чтобы добраться до того места, где возникает проблема. Отладчик дает Вам возможность выполнять сразу большой фрагмент программы до той точки, где вы хотите начать выполнение по шагам.
Чтобы задать в программе точку, до которой она должна выполняться, а затем остановиться, используйте команду Run → GoTo Cursor или клавишу F4. (Этим вы сообщите отладчику, что не хотите выполнять программу по шагам, пока не достигнете заданной точки.) Установите курсор на той строке, где вы хотите возобновить управление отладкой, затем нажмите клавишу F4. Заметим, что Вы можете сделать это как в начале сеанса отладки, так и когда уже выполните часть программы по шагам или протрассируете.
Внимание: С использованием этой команды связана одна особенность: если Вы хотите, чтобы программа выполнилась до определенной строки, и устанавливаете курсор внутри модуля (Unit), то этого не произойдет, Вы просто получите ошибку Cannot Run a Unit , и этим все закончится, т.к. IDE понимает это действие, как приказ запустить модуль, чего делать нельзя. Требуется объяснить IDE, чего Вы от нее хотите примерно так: «Запусти основную программу, и только потом выполни все, до текущего положения курсора». Для этого надо зайти в меню Compile → Primary File, указать системе основной файл (НЕ модуль) Вашего приложения, и
только после этого установить курсор внутрь модуля, и нажать F4…
Казалось бы, что поменялось? А вот что: теперь IDE точно знает — основным
файлом приложения является тот, который был установлен, как Primary File,
следовательно, совершенно нет необходимости запускать МОДУЛЬ, достаточно
запустить основной файл, и остановиться тогда, когда выполнение дойдет до
нужной строки в модуле.
Что такое окно Watches и как им пользоваться?
Выполнение программы по шагам или ее трассировка могут помочь Вам найти ошибки в алгоритме программы, но обычно желательно также знать, что происходит на каждом шаге со значениями отдельных переменных. Можно, конечно, по-старинке добавлять в необходимые места программы оператор WriteLn, который распечатает значение контролируемой переменной (а иногда просто нет другого выбора, например, при компиляции крупных проектов на Турбо Паскале возникает необходимость вообще отказаться от IDE, и пользоваться автономной версией компилятора — TPC — запускаемой из командной строки), но если уж есть возможность пользоваться средой программирования — то лучше использовать для контроля за переменными одно из специальных средств IDE: окно Watches (Просмотр) или диалоговое окно Evaluate and Modify (Вычисление и модификация).
Оба средства вычисления и просмотра работают на уровне выражений, поэтому важно определить, что считается выражением. Выражение состоит из констант, переменных и структур данных, скомбинированных с помощью операций и большинства встроенных функций. Почти все, что вы можете использовать в правой части оператора присваивания, может также использоваться в качестве отладочного выражения.
Элементы выражений отладчика
┌────────────────┬────────────────────────────────────────────────────┐ │Элемент │Допустимые значения │ │выражения │ │ ├────────────────┼────────────────────────────────────────────────────┤ │ │Все допустимые типы: Boolean, Byte, Char, │ │Константы │перечислимый тип, Integer, Longint, Real, Shortint, │ │ │Word и строковый тип. │ ├────────────────┼────────────────────────────────────────────────────┤ │Переменные │Все типы, включая типы, определенные пользователем. │ ├────────────────┼────────────────────────────────────────────────────┤ │ целочисленный│Любое целочисленное выражение с переменными │ │тип │границами диапазона. │ ├────────────────┼────────────────────────────────────────────────────┤ │ тип с │Любые выражения с плавающей точкой или целочисленные│ │плавающей точкой│выражения; лишние значащие цифры отбрасываются. │ ├────────────────┼────────────────────────────────────────────────────┤ │ │Любое символьное выражение, включая печатаемые │ │ символьный │символы в одинарных кавычках, целочисленные │ │тип │выражения, тип которых приведен к типу Char, и │ │ │контанты ASCII (#xx). │ ├────────────────┼────────────────────────────────────────────────────┤ │ булевский тип│True, False и все булевские выражения. │ ├────────────────┼────────────────────────────────────────────────────┤ │ перечислимый │Любые совместимые перечислимые константы или │ │тип │целочисленные выражения в рамках диапазона, тип │ │ │которых приведен к совместимому перечислимому типу. │ ├────────────────┼────────────────────────────────────────────────────┤ │ │Любые совместимые указатели или выражения с │ │ указатель │приведенными к ним типами; функция Ptr с │ │ │соответствующим параметрами. │ ├────────────────┼────────────────────────────────────────────────────┤ │ │Любая строковая константа (текст в одинарных │ │ строковый тип│кавычках); строковые переменные; строковые │ │ │выражения, состоящие из конкатенированных строковых │ │ │констант и переменных. │ ├────────────────┼────────────────────────────────────────────────────┤ │ │Любая множественная константа; любое выражение, │ │ множество │совместимое с множественным типом, в котором │ │ │используются операции +, - и *. │ ├────────────────┼────────────────────────────────────────────────────┤ │Приведение типа │Соблюдаются стандартные правила Паскаля. │ ├────────────────┼────────────────────────────────────────────────────┤ │Операции │Все операции Borland Pascal. │ ├────────────────┼────────────────────────────────────────────────────┤ │Встроенные │Все функции, допустимые в выражениях-константах. │ │функции │ │ ├────────────────┼────────────────────────────────────────────────────┤ │Массивы │Массивы Borland Pascal - Mem, MemL, MemW. │ └────────────────┴────────────────────────────────────────────────────┘
Разберем использование окна Watches
Вначале это окно нужно отобразить на экране. Делается это выбором пункта
меню Debug → Watch. На экране появится пустое окно с соответствующим заголовком.
Теперь запускаем программу в пошаговом режиме (нажатием клавиши F7, или
выбором меню «Run → Trace Into»), в редакторе устанавливаем курсор на
название переменной, за которой будем «следить», и жмем Ctrl+F7 (или меню
«Debug → Add Watch…») и подтверждаем выбор нажатием «Ok»… Всё…
Переменная добавлена в окно Watches, и можно наблюдать за ее значением на Watch каждом шаге выполнения программы…
Примечание: Если выбрать переменную для просмотра без предварительного
отображения пустого окна Watches на экране, ничего страшного не произойдет: IDE автоматически откроет окно Watches самостоятельно.
Например, после выполнения выделенной строки
i := 15;
значение переменной i будет уже равно не 0, а 15…
В окне Watches могут отображаться любые типы констант/переменных, объявленных в программе. Например, если описан массив …
const arr: array[1 .. 10] of integer = ( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 );
… то можно просмотреть одновременно (!!!) как весь этот массив, так
и его левую и правую части… Для этого достаточно ввести во втором и Просмотр третьем случае не только название массива, но и стартовый элемент, и массива (через запятую) число повторений.
Кроме массивов и переменных встроенных типов возможно просматривать Просмотр также и записи (либо в простом формате — только имя переменной, либо в записи специальном — с добавлением спецификатора R.
Все возможные спецификаторы перечислены в таблице (перед любым спецификатором можно указать количество повторений, а если не нужно преобразовывать тип переменной, то сам спецификатор можно не указывать, чем я уже пользовался выше, при выводе части массива arr):
┌──────┬─────────────┬────────────────────────────────────────────────────────┐ │ │Тип, на │ │ │Символ│который он │Функция │ │ │влияет │ │ ├──────┼─────────────┼────────────────────────────────────────────────────────┤ │$, H │целочисленные│Шестнадцатиричный. Выводит целочисленные значения с │ │или X │типы │префиксом $, включая те, которые содержатся в структуре │ │ │ │данных. │ ├──────┼─────────────┼────────────────────────────────────────────────────────┤ │ │Char, │Символьный. Выводит специальные символы для кодов ASCII │ │C │строковые │0..31. По умолчанию такие символы выводятся в виде │ │ │типы │значений #xx. │ ├──────┼─────────────┼────────────────────────────────────────────────────────┤ │ │целочисленные│Десятичный. Выводят целочисленные значения в десятичном │ │D │типы │виде (включая те, которые содержатся в структурах │ │ │ │данных). │ ├──────┼─────────────┼────────────────────────────────────────────────────────┤ │Fn │с плавающей │С плавающей точкой. Выводит n значащих цифр, где n лежит│ │ │точкой │в диапазоне 2..18 (по умолчанию - 11). │ ├──────┼─────────────┼────────────────────────────────────────────────────────┤ │ │ │Дамп памяти. Выводит n байт памяти, начиная с адреса, │ │nM │все │указываемого выражением. Если n не задано, то по │ │ │ │умолчанию оно равно значению размера в байтах типа │ │ │ │переменной. │ ├──────┼─────────────┼────────────────────────────────────────────────────────┤ │P │указатели │Указатель. Выводит указатели в формате сегм:смещ (а не │ │ │ │Ptr(сегм:смещ), как это делается по умолчанию. │ ├──────┼─────────────┼────────────────────────────────────────────────────────┤ │R │записи, │Запись. Выводит имена полей, например, (X:1;Y:10; Z:5) │ │ │объекты │вместо (1, 10,5). │ ├──────┼─────────────┼────────────────────────────────────────────────────────┤ │ │ │Строки. Выводит символы ASCII 0..31 в виде #xx. │ │S │Char, строки │Использует только для модификации дампов памяти (см. │ │ │ │выше nM). │ └──────┴─────────────┴────────────────────────────────────────────────────────┘
Окно Evaluate and Modify
Но кроме простого просмотра значений той или иной переменной или выражения,
существует средство, позволяющее вам в любой момент вычислять выражения и
изменять на этапе выполнения значения переменных. Этим средством и является
диалог Evaluate and Modify (Вычисление и модификация).
Вычисление выражений
Чтобы вычислить выражение, выбираем команду Debug → Evaluate/Modify или нажимаем клавиши Ctrl+F4. Отладчик выводит диалоговое окно Evaluate and Modify (Вычисление и модификация). Здесь (в поле ввода Expression) можно занести любое допустимое выражение , или выбрать его из списка ранее вычисленных при помощи этого же диалога выражений и отредактировать.
После нажатия на Enter или щелчка мышью на кнопке Evaluate (Вычислить), текущее значение выражения будет показано в поле Result (Результат).
Примечание: если в поле Expression введено выражение, которое не может быть вычислено интегрированной средой, то в поле Result появится вот такая надпись: «Cannot evaluate this expression».
Модификация переменных
Кроме этого, во время отладки с помощью диалогового окна Evaluate and Modify существует возможность поменять значение переменной на любое другое, чтобы проверить работу программы с другим, вновь присвоенным значением переменной. Для этого нужно установить курсор на имени переменной, и выбрать в меню Debug → Evaluate/Modify… (или просто нажать Ctrl+F4)…
В появившемся окне в поле Expression (Выражение) достаточно ввести имя переменной (или ничего не делать, если имя уже введено), и нажать кнопку Evaluate… Текущее значение выбранной переменной будет отображено в поле Result. Если оно же отображается и в поле New Value, это значит, что у Вас есть возможность прямо сейчас поменять это значение на любое другое (разумеется, совместимое по присваиванию с типом выбранной переменной; присваивать строке целому числу Вам никто не позволит, также, как и, например, записать в целочисленную переменную значение 3.14159), и применить новое значение переменной, не перезапуская программу…
Например, допустим, что программа имеет вид:
var i: integer; begin for i := 1 to 20 do writeln(i); readln; end.
, и Вам захотелось попасть в точку, где распечатывается значение i = 20 (желание далеко не самое сумасшедшее, представьте, например, что вместо простого распечатывания значения i там будет вызов какой-нибудь функции, которую надо прогнать пошагово при определенном значении i, да еще и функция может быть длинной и долго выполняться), но не очень хочется нажимать F7 почти 20 раз и приходить в нужную точку «естественным путем». Что делаем? А вот что:
Добавляем значение i в окно Watches, начинаем выполнять программу пошагово (F7)… Я остановился, когда значение i было равно трем, хотя это же самое можно было сделать и сразу после входа в цикл, то есть как только i стало равно единице.
Теперь ставим курсор под название переменной i и жмем Ctrl+F4 для вызова нужного нам окна… Состояние экрана, которое должно получиться, видно на скриншоте…
Переходим в поле New Value (как я говорил, если в нем записано текущее значение переменной, то нам будет позволено его сменить), печатаем в нем значение 20, и жмем на «Modify»…
Как видим, значение i в Watches тоже поменялось на 20, теперь спокойно закрываем окно «Evaluate and Modify» (кнопкой Cancel), и продожлжаем выполнять программу пошагово…
Таким образом, мы пропустили все НЕинтересующие нас в данном случае шаги,
выполнение которых могло занять значительное время…
Окно Call Stack — что это такое?
В IDE Паскаля есть еще одно очень удобное средство отладки — просмотр стека вызовов подпрограмм. Представьте себе, что программа имеет не только основную часть, но и несколько процедур/функций, вызывающих друг друга. В таком случае при пошаговой отладке становится сложно держать в памяти, какая именно процедура вызвала ту, что выполняется сейчас, и куда, соответственно, вернется управление после завершения текущей подпрограммы.
Да и не нужно этого держать в голове. Для этого существует такое средство, как «Call Stack» (вызывается из меню Debug → Call Stack или просто Ctrl+F3). Например, пусть наша программа имеет вид:
function fact(n: longint): longint; begin if n = 0 then fact := 1 else fact := n * fact(n - 1); end; function b(n: longint): integer; begin b := 2 * fact(n); end; begin writeln( b(10) ); end.
Если начать выполнять ее пошагово, очень скоро можно запутаться в том, что именно сейчас выполняется (факториал какого числа вычисляется в данный момент, к примеру), и что еще осталось НЕзавершенным. А если программа будет в 10 раз длиннее, и будет содержать не 2, а 10 процедур/функций? В таком случае достаточно вызвать окно Call Stack (способ вызова — выше), и посмотреть, что именно в данный момент выполняется (то есть находится на першине стека вызовов), и что еще выполняться будет (находится ниже в списке), вплоть до Program, обозначающего, самый нижний уровень — основную программу…
Вот, например, в данном случае: выполняется функция вычисление факториала 8, которая вызвана из нижестоящей в списке функции вычисления факториала 9, которая в свою очередь… Ну, дальше все понятно… При продолжении пошагового выполнения этой программы в окно Call Stack будут добавляться новые и новые вызовы Fact (7), Fact(6), … до Fact(0); потом рекурсия начнет раскручиваться обратно…
Кстати, Call Stack — незаменимый помощник именно при работе с рекурсивными подпрограммами, поскольку дает возможность контролировать последовательность вызовов рекурсивной функции, и на ранней стадии определить, например, бесконечную рекурсию…
Например, здесь — совершенно очевидно, что рекурсивная функция оформлена неверно (отсутствует ветка Else), сразу после того, как в окне Call Stack появились вызовы f (-1) и f(-2)…
Еще одно полезное применение окна Call Stack — если вы случайно начали трассировку кода, который хотели бы выполнить за один шаг. В стеке вызовов вы можете найти тот вызов, который начали трассировать по ошибке, затем выбрать команду Run to Cursor, чтобы выполнить за один шаг остальную часть вызова.
Что такое точки останова программы?
Кроме всех вышеперечисленных возможностей, значительно облегчающих жизнь программисту, в IDE Паскаля встроено еще одно средство, очень мощное и эффективное (при правильном использовании)… Это — работа с точками останова программы (BreakPoints).
Точка останова — это обозначенная в коде программы позиция, в которой вы хотите прекратить выполнение программы и вернуть выполнение отладчику. В этом смысле точка останова работает аналогично команде GoTo Cursor, при которой программа выполняется обычным путем до достижения определенной точки. Основное различие состоит в том, что вы можете задать несколько точек останова и точки останова, которые будут срабатывать не при каждом их достижении.
Допустим, есть следующая программа:
const parameter = 10; function f(x: integer): integer; begin f := 10 * parameter - sqr(x); end; var i, j: integer; arr: array[1 .. 20] of real; begin for i := 1 to 20 do begin j := f(i); arr[i] := (15 * j / parameter) + i / j - 8; end; { ... } end.
(не обольщайтесь, программа может быть не в 17, а в 1700 строк длиной, и функция f может быть гораздо более сложной, так же как и способ ее вызова)…
Естественно, запустив эту программу, получаем:
Runtime error 200 at 0006:0004.
, из чего заключаем, что где-то в программе происходит деление на 0. Ну, где
оно происходит, понятно. А вот на какой итерации? Чему равно i, при котором
происходит эта ошибка? Можно, конечно, воспользоваться старым и проверенным
способом, и сделать так:
const parameter = 10; function f(x: integer): integer; begin f := 10 * parameter - sqr(x); end; var i, j: integer; arr: array[1 .. 20] of real; begin for i := 1 to 20 do begin j := f(i); writeln('j = ', j); arr[i] := (15 * j / parameter) + i / j - 8; end; { ... } end.
, после чего нам будут распечатаны все значения j, для которых программа отработала нормально, и еще одно, при котором как раз и произошло «Деление на Ноль». Но для этого нужно вносить изменения в программу. А можно обойтись без её изменений… Используя точку останова…
Для этого проделаем следующее… Во-первых, добавим переменную i в список Watches, так как нам нужно найти именно «при каком i программа вылетает».
Далее — установим курсор на той строке программы, где происходит деление, и выберем в меню пункт «Debug → Add Breakpoint…» Экран примет вид, показанный на снимке справа.
Примечание: строка, на которую устанавливается BreakPoint, должна содержать выполняемый код и не может быть комментарием, описанием или пустой строкой…
В поле Condition внесем условие, при котором следует остановить программу (условие вводится так же как и при использовании условных операторов в программе, только Условный If здесь присутствовать не должно), и подтверждаем установку BreakPoint-а нажатием кнопки «Ok»:
Строка, в которой установлен хотя бы один BreakPoint (а устанавливать можно несколько точек останова для программы, причем даже на одной строке, но с разными условиями, может быть установлено более одного BreakPoint-а) меняет цвет на красный…
Если теперь запустить программу (обычным способом — через Ctrl+F9, или пошагово, не имеет значения), то как только значение j в Условный выделенной строке станет равным 0, прогон программы будет приостановлен с выдачей вот такого сообщения:
Как видим (в окне Watches), происходит это при i = 10… Что и требовалось
определить…
Чтобы просмотреть, какие BreakPoint-ы были установлены в программе, достаточно зайти в меню «Debug → BreakPoints», и будет выведен список всех точек останова для данной программы:
Нажатием на «Clear All» можно удалить все точки останова сразу, «Delete» удалит только подсвеченный BreakPoint, а «Edit»-ом можно отредактировать текущий (подсвеченный) BreakPoint — подкорректировать условие, поменять номер строки, в которой должна производиться проверка, изменить счетчик числа проходов (задание для точки останова счетчика проходов сообщает отладчику, что останавливать программу нужно не при каждом достижении точки останова, а только на n-ый раз. То есть, если счетчик проходов равен 3, то отладчик останавливает программу только при третьем достижении данной точки останова) и т.д.
Поиск нужного места
IDE предусматривает два способа поиска в программе заданного места. Простейший способ предоставляет команда Find Procedure (Поиск процедуры) из меню Search. Эта команда запрашивает у Вас имя процедуры или функции, затем находит соответствующую строку в файле, где определяется эта подпрограмма. Этот подход полезно использовать при редактировании, но его можно комбинировать с возможностью выполнения программы до определенной точки, чтобы пройти программу до той части кода, которую вы хотите отладить.
Повторное выполнение (сброс программы)
В ходе сеанса отладки иногда желательно начать все сначала. Выберите команду Run → Reset Program или нажмите клавиши Ctrl+F2. Это приведет к полному сбросу, так что выполнение по шагам, или трассировка начнется в начале основной программы.
Отслеживание вывода программы
При выполнении программы по шагам часто полезно просмотреть вывод программы, называемый экраном пользователя. IDE предоставляет несколько способов просмотра экрана пользователя.
Переключение экранов
В любой момент сеанса отладки вы можете выполнять переключение экрана IDE и экрана пользователя. Чтобы вывести экран пользователя, нажмите клавиши Alt+F5. Чтобы вернуться в IDE, нажмите любую клавишу или щелкните «мышью».
Окно Output
IDE для DOS предусматривает для экрана пользователя окно, которое называется окном вывода. Выбрав команду меню Debug → Output, вы можете открыть (вывести на передний план) активное окно, содержащее вывод программы. Настроить размер этого окна можно аналогично окну редактирования.
Ошибки компиляции (Турбо-Паскаль)
Среда Турбо-Паскаля обладает мощными средствами обнаружения и локализации ошибок. В случае обнаружения ошибки она идентифицируется курсором. При этом в верхней строке окна редактора появляется диагностическое сообщение. После нажатия на любую клавишу, кроме(F1) верхняя строка восстанавливает свой первоначальный вид, и среда переходит к режиму редактирования. Если после появления сообщения об ошибке нажать функциональную клавишу F1, на экране появиться окно справочной службы с детальной информацией об ошибке и рекомендациями по ее устранению. Некоторые ошибки в исходном тексте обнаруживаются не сразу, а в ходе продолжающегося контекстного разбора. Например, несоответствие типов в операторе присваивания не может быть обнаружено до тех пор, пока не будет вычислено целиком выражение в правой части этого оператора. В таких случаях ищите ошибку слева от курсора или в предыдущей строке текста. Ниже приводятся сообщения об ошибках в том виде, в каком они появляются в верхней строке окна редактора, а также перевод сообщений справочной службы.
1. Out of memory (Выход за границы памяти)
2. Identifier expected (Не указан идентификатор)
3. Unknown identifier (Неизвестный идентификатор)
4. Duplicate identifier (Двойной идентификатор)
5. Syntax error (Синтаксическая ошибка)
6. Error in integer constant (Ошибка в целой константе)
7. String constant exceeds fine (Строковая константа превышает допустимые размеры)
8. Error in real constant (Ошибка в вещественной константе)
9. Unexpected end of file (Не найден конец файла)
10. Line too tons (Слишком длинная строка)
11. Type identifier expected (Здесь нужен идентификатор типа)
12. Too many open files (Слишком много открытых файлов)
13. File not found (Файл не найден)
14. Invalid file name (Неверное имя файла)
15. Disk full (Диск заполнен)
16. Undefiner typein pointer definition (Неопределенный тип в объявлении указателя)
17. Variable identifier expected (Отсутствует идентификатор переменной)
18. Error in type (Ошибка в объявлении типа)
19. Structure too large (Слишком большая структура)
20. Set-base type of range (Базовый тип множества нарушает границы)
21. File components may not be files (Компонентами файла не могут быть файлы)
22. Invalid string length (Неверная длина строки)
23. Type mismatch (Несоответствие типов)
24. Invalid subrange base type (Неправильный базовый тип для типа диапазона)
25. Lower bound greater than upper bound (Нижняя граница больше верхней)
26. Ordinal type expected (Нужен порядковый тип)
27. Integer constant expected (Нужна целая константа)
28. Consant expected (Нужна константа)
29. Integer or real constant expected (Нужна целая или вещественная константа)
30. Pointer type identifier expected (Нужен идентификатор типа)
31. Invalid function result type (Неправильный тип результата функции)
32. Label identifier expected (Нужен идентификатор метки)
33. BEGIN expected (Нужен BEGIN)
34. END expected (Нужен END)
35. Integer expression expected (Нужно выражение типа INTEGER)
36. Ordinal expresiion expected (Нужно выражение перечисляемого типа)
37. Boolean expression expected (Нужно выражение типа BOOLEAN)
38. Operand types do not match operator (Типы операндов не соответствуют операции)
39. Error in expression (Ошибка в выражении)
40. Illegal assigment (Неверное присваивание)
41. Field identifier expected (Нужен идентификатор поля)
42. Code segment too large (Сегмент кода слишком большой)
43. Data segment too large (Сегмент данных слишком велик)
44. DO expected (Нужен оператор DO)
45. OF expected (Требуется OF)
46. INTERFACE expected (Требуется интерфейсная секция)
47. Invalid relocatable refence (Неправильная перемещаемая ссылка)
48. THEN expected (Требуется THEN)
49. TO or DOWNTO expected (Требуется TO или DOWNTO)
50. Undefiner forward (Неопределенное опережающее описание)
51. Invalid typecast (Неверное преобразование типа)
52. Division by zero (Деление на нуль)
53. Invalid file type (Неверный файловый тип)
54. Cannot Read or Write variables of this type (Нет возможности считать или записать переменые данного типа)
55. Pointer variable expected (Нужно использовать переменную-указатель)
56. String variable expected (Нужна строковая переменная)
57. String expression expected (Нужно выражение строкового типа)
58. Circular unit refence (Перекрестная ссылка модулей)
59. Unit name mismatch (Несоответствие имен программных модулей)
60. Unit version masmatch (Несоответствие версий модулей)
61. Internal stack overflow (Переполнение внутреннего стока)
62. Unit file format error (Ошибка формата файла модуля)
63. Implementation expected (Отсутствует исполняемая часть модуля)
64. Constant and case types do not match (Типы констант и тип выражений оператора CASE не соответствуют друг другу)
65. Record or object variable expected (Нужна переменная типа запись или объект)
66. Constant out of range (Константа нарушает границы)
67. File variable expected (Нужна файловая переменная)
68. Pointer expression expected (Нужно выражение типа указатель)
69. Integer or real expression expected (Нужно выражение вещественного или целого типа)
70. Label not within current block (Метка не находится внутри текущего блока)
71. Label already defined (Метка уже определена)
72. Undefined label in processing statement part (Неопределенная метка в предшествующем разделе операторов)
73. Invalid @ argement (Неправильный аргумент операции @)
74. Unit expected (Нужно кодовое слово Unit)
75. <;> expected (Нужно указать <;>)
76. <:> expected (Нужно указать <:>)
77. <,> expected (Нужно указать <,>)
78. <(> expected (Нужно указать <(>)
79. <)> expected (Нужно указать <)>)
80. <-> expected (Нужно указать <->)
81. <:=> expected (Нужно указать <:=>)
82. <[> or <(.>expected (Нужно указать <[> или <(.>)
83. <]> or <.)> expected (Нужно указать <]> или <.)>)
84. <.> expected (Нужно указать <.>)
85. <..> expected (Нужно указать <..>)
86. Too many variables (Слишком много переменных)
87. Invalid FOR control variable (Неправильный параметр цикла оператора FOR)
88. Integer variable expected (Нужна переменная целого типа)
89. Files types are not allowed here (Здесь не могут использоваться файлы)
90. String length mismatch (Несоответствие длины строки)
91. Invalid orering of fields (Неверный порядок полей)
92. String constant expected (Нужна константа строкового типа)
93. Integer or real variable expected (Нужна переменная типа INTEGER или REAL)
94. Ordinal vairale expected (Нужна переменная порядкового типа)
95. Character expression expected (Предшествующее выражение должно символьный тип)
96. Overflow in arithmetic operation (Переполнение в арифметической операции)
97. No enclosing For, While or Repeat statement (Операторы For, While или Repeat без окончания)
98. Case constant out of range (Константа Case нарушает допустимые границы)
99. Error in statement (Ошибка в операторе)
100. Must be in 8087 mode to compile this (Для компиляции необходим режим 8087)
101. Target address not found (Указанный адрес не найден)
102. Include files are not allowed here (Здесь не допускаются включаемые файлы)
103. Invalid qualifier (Неверный квалификатор)
104. Invalid variable refence (Недействительная ссылка на переменную)
105. Too many symbols (Слишком много обозначений)
106. Statement part too large (Слишком большой раздел операторов)
107. Files must be var parameters (Файлы должны передаваться по имени)
108. Header does not match previous definition (Заголовок не соответствует предыдущему определению)
109. Cannot evaluate this expression (Некорректное вычисление выражения)
110. Invalid format specifier (Неверный спецификатор формата)
111. Invalid indirect refence (Недопустимая косвенная ссылка)
112. Structured variable are not allowed here (Здесь нельзя использовать переменную структурного типа)
113. Cannot evaluate without System unit (Нельзя вычислить выражение без модуля SYSTEM)
114. Cannot access this symbol (Нет доступа к данному символу)
115. Invalid floating-point operation (Недопустимая операция с плавающей запятой)
116. Procedure or function variable expected (Должна использоваться переменная процедурного типа)
117. Invalid procedure or function refence (Недопустимая ссылка на процедуру или функцию)
118. File access denied (Отказ в доступе к файлу)
119. Object type expected (Здесь должен быть тип OBJECT)
120. Local object types are not allowed (Нельзя объявлять локальные объекты)
121. VIRTUAL expected (Пропущено слово VIRTUAL)
122. Method identifier expected (Пропущен идентификатор инкапсулированного правила)
123. Virtual constructor are not allowed (Конструктор не может быть виртуальным)
124. Destructor identifier expected (Пропущен идентификатор деструктора)
125. Fail only allowed within constructor (Неизвестный модуль)
126. Invalid combination of opcode and operends (Недопустимая комбинация кода команды и операндов)
124. Memory refence expected (Нужна ссылка на память)
125. Invalid symbol refence (Неверное обозначение ссылки)
126. Code generation error (Ошибка при генерации программы)
127. Duplicate dynamic method index (Повторяется индекс динамического правила)
128. Procedure or function identifier expected (Нужен идентификатор процедуры или функции)
2) Ошибки, возникающие во время выполнения программы
Некоторые ошибки, обнаруженные во время выполнения программы, приводят к
появлению на экране сообщения вида:
Runtime error nnn at xxxx:yyyy
(ошибка периода исполнения nnn по адресу xxxx:yyyy), где nnn- номер ошибки,
xxxx:yyyy- адрес (сегмент и смещение). После этого сообщения программа завершает
свою работу.
Ошибки периода исполнения делятся на четыре категории:
1) Ошибки, обнаруживаемые ДОС (коды ошибок 1-99);
2) Ошибки вводавывода (100-149);
3) Критические ошибки (150-199);
4) Фатальные ошибки (200-255);
3) Ошибки, обнаруживаемые ДОС
1. Invalid function number (Неверный номер функции)
2. File not found (Не найден файл)
3. Path not found (Путь не найден)
4. Too many open files (Слишком много открытых файлов)
5. File access defined (Отказано в доступе к файлу)
6. Invalid file handle (Недопустимый файловый канал)
7. Invalid file access code (Недействительный код доступа к файлам)
8. Invalid drive number (Недопустимый номер дисковода)
9. Cannot remove current directory (Нельзя удалить текущий каталог)
10. Cannot rename across drives (Нельзя при переименовании указывать разные дисководы)
4) Ошибки вводавывода
1. Disk read error (Ошибка чтения с диска)
2. Disk write error (Ошибка записи на диск)
3. File not assigned (Файлу не присвоено имя)
4. File not open (Файл не открыт)
5. File not openor output (Файл не открыт для вывода)
6. Invalid numeric format (Неверный числовой формат)
5) Критические ошибки
1. Disk is write protected (Диск защищен от записи)
2. Unknown unit (Неизвестный модуль)
3. Drive not ready (Дисковод находится в состоянии «Не готов «)
4. Unknown command (Неопознанная команда)
5. CRC error in data (Ошибка в исходных данных)
6. Bad drive request strukture length (При обращении к диску указана неверная длина структуры)
7. Disk seek error (Ошибка при операции установки головок на диск)
8. Unknown media type (Неизвестный тип носителя)
9. Sector not found (Сектор не найден)
10. Printer out of paper (Кончилась бумага на принтере)
11. Device writeemit (Ошибка при записи на устройство)
12. Device read fault (Ошибка при чтении с устройства)
13. Hardware failure (Сбой аппаратуры)
6) Фатальные ошибки
Эти ошибки всегда приводят к немедленной остановке программы.
1. Division by zero (Деление на нуль)
2. Range check error (Ошибка при проверке границ)
3. Stack overflow error (Переполнение стека)
4. Hearp overflow error (Переполнение кучи)
5. Invalid pointer operation (Недействительная операция с указателем)
6. Floating point overflow (Переполнение при операции с плавающей запятой)
7. Invalid floating point operation (Недопустимая операция с плавающей запятой)
8. Floating point underflow (Исчезновение порядка при операции с плавающей запятой)
9. Object not initialized (Не инициирован объект)
10. Call to abstract method (Вызов абстрактного правила)
2008-02-10 • Просмотров [ 19479 ]
Содержание
Отладка программ в Turbo Pascal
Автор: volvo877 (он же и volvo71)
Ссылка на оригинал статьи
(не хватает картинок из статьи)
Каждый программист знает, что программу надо не только написать, иначе говоря —
«заставить работать», а еще и отладить, т.е. заставить ее работать правильно…
Для того, чтобы делать это быстро и эффективно, желательно научиться
пользоваться встроенными в IDE средствами отладки программ…
Интегрированная интерактивная среда разработки программ Borland Pascal (IDE)
включает в себя ряд средств, облегчающих разработку программ: автоматическое
управление проектами, средств обеспечения модульной структуры программы,
быструю компиляцию и простые в использовании оверлеи. Но, несмотря на все это,
Ваша программа все равно может содержать ошибки, что не позволит ей корректно
работать.
IDE для DOS Borland Pascal предоставляет вам инструментальные средства для
отладки программ, то есть поиска и исправления ошибок. В этой статье
описываются инструментальные средства и процедуры отладки программы в
интегрированной среде Борланд Паскаль (большинство описанных возможностей
применимо также к IDE FreePascal-я).
Что такое отладка?
Отладка — это процесс поиска и исправления ошибок в программе, препятствующих
корректной работе программы. Перед тем как углубиться в специфические средства
IDE, которые помогают при отладке, дадим краткое описание видов ошибок, которые
Вы можете наблюдать, и различного рода операций, которые будут использоваться
для их поиска.
Какие существуют виды ошибок?
Существует три основных типа ошибок:
-
Ошибки этапа компиляции
-
Ошибки этапа выполнения
-
Логические ошибки
Ошибки этапа компиляции
Ошибки этапа компиляции или синтаксические ошибки происходят, когда
исходный код программы нарушает правила синтаксиса Паскаля. Компилятор не
может скомпилировать программу, пока она не будет содержать только
допустимые операторы Паскаля. Когда компилятор встречает оператор, который он не может распознать, соответствующий файл выводится в окне
редактирования, курсор устанавливается на то место, которое не понял
компилятор, и выводится сообщение об ошибке.
Наиболее общей причиной ошибок этапа компиляции являются ошибки набора (опечатки), пропущенные точки с запятой, ссылки на неописанные переменные, передача неверного числа (или типа) параметров процедуры или функции и присваивание переменной значения неверного типа.
После исправления ошибки компиляцию необходимо выполнить заново. После устранения в программе всех синтаксических ошибок и ее успешной компиляции программа будет готова к выполнению и поиску ошибок этапа выполнения и логических ошибок.
Ошибки этапа выполнения
Ошибки этапа выполнения или семантические ошибки происходят, когда вы
запускаете успешно откомпилированную программу, которая при выполнении
делает что-то недопустимое. То есть, программа содержит допустимые
операторы Паскаля, но при выполнении этих операторов что-то происходит
неверно. Например, программа может пытаться открыть для ввода
несуществующий файл или выполнить деление на ноль.
Когда такая ошибка обнаруживается, выполнение программы завершается, и выводится сообщение следующего вида:
Run-time error ## at seg:ofs
Если Вы выполняете программу из IDE, она автоматически находит оператор,
вызвавший ошибку (как и в случае синтаксических ошибок). Если же программа выполняется вне IDE (EXE-файл запускается из командной строки или файлового менеджера ОС), то вы можете запустить IDE и, чтобы найти вызвавший ошибку оператор, использовать команду Search → Find Error, которая дает вам адрес сегмента и смещения (seg:ofs).
Логические ошибки
Логические ошибки — это ошибки проектирования и реализации программы. То
есть, операторы, используемые в программе, допустимы, и что-то делают, но
не то, что Вы предполагали. Эти ошибки часто трудно отследить, поскольку
IDE не может найти их автоматически, как синтаксические и семантические
ошибки. К счастью, IDE включает в себя также и средства отладки, помогающие вам найти логические ошибки.
Логические ошибки приводят к некорректному или непредвиденному изменению значений переменных, неправильному отображению графики или невыполнению кода тогда, когда это ожидается. В остальной части этой статьи обсуждаются методы отслеживания логических ошибок.
Иногда, когда программа делает что-то непредвиденное, причина достаточно очевидна, и Вы можете быстро исправить код программы. Но другие ошибки более трудноуловимы и вызываются в результате взаимодействия различных частей программы. В этих случаях лучше всего остановить вашу программу в заданной точке, пройти ее шаг за шагом и просмотреть состояние переменных и выражений.
Пошаговый прогон: какая разница между F4, F7 и F8?
Основной смысл использования встроенного отладчика состоит в управляемом
выполнении. Отслеживая выполнение каждой инструкции, Вы можете легко
определить, какая часть Вашей программы вызывает проблемы. В отладчике
предусмотрено пять основных механизмов управления выполнением программы,
которые позволяют вам:
-
Выполнять инструкции по шагам
-
Трассировать инструкции
-
Выполнять программу до заданной точки
-
Находить определенную точку
-
Выполнять сброс программы
Само по себе выполнение программы по шагам может быть недостаточно полезным, разве что поможет найти то место, где что-то происходит совершенно неверно. Но управляемое выполнение дает Вам возможность проверять состояние программы и ее данных, например, отслеживать вывод программы и ее переменные.
Что такое шаг?
Когда Вы отлаживаете программу, наименьшим выполняемым элементом является
строка. Это означает, что Вы можете управлять отладкой до уровня отдельной строки исходного кода программы. Поэтому, если на одной строке программы содержится несколько операторов Паскаля, эти операторы не могут быть отлажены индивидуально. С другой стороны, с целью отладки оператор можно разбить на несколько строк, каждая из которых будет выполняться за один шаг.
Все выполнение в отладчике, включая выполнение по шагам, трассировку и останов, основывается на строках. Подсвечивая строку, встроенный отладчик всегда сообщает Вам, какую строку он выполнит на следующем шаге (строка выполнения). Строка выполнения выводится цветом, отличным от нормального цвета. Благодаря этому Вы можете легко видеть, где находитесь.
Выполнение программы по шагам
Выполнение по шагам — это простейший способ выполнения программы по
элементарным фрагментам. Выбор команды Run → Step Over или нажатие клавиши F8 вызывает выполнение отладчиком всего кода в операторе, указанном строкой выполнения, включая любые вызываемые на ней процедуры или функции, пока управление не вернется обратно к вам. После этого строка выполнения указывает следующий выполняемый оператор.
Возьмем, например, следующую программу:
program StepTest; function Negate(X: Integer): Integer; begin Negate := -X; end; var I: Integer; begin for I := 1 to 10 do Writeln(Negate(I)); end.
Если в окне редактирования Вы выведете StepTest и нажмете клавишу F8, то строка выполнения перемещается на оператор begin в начале основного цикла, поскольку это первое, что выполняется в программе. Второе нажатие клавиши F8 выполняет begin и перемещает строку выполнения вниз до оператора for на следующей строке.
После этого нажатие F8 вызывает выполнение всего цикла for; на экран
пользователя выводятся числа от -1 до -10, а строка выполнения перемещается к end.
Хотя функция Negate и вызывается 10 раз, строка выполнения никогда на нее не перемещается. Выполнение по шагам позволяет отладчику не показывать детали любых вызовов для отдельной строки. Выполнение по шагам вызывает выполнение всего цикла for сразу, поэтому Вы не сможете видеть изменения в ходе выполнения цикла. Если же Вы хотите видеть подробности выполнения цикла, внесите в пример следующее простое изменение.
begin for I := 1 to 10 do WriteLn(Negate(I)); end.
Поскольку оператор Паскаля может занимать несколько строк, такая программа будет в точности эквивалентна предыдущей версии, и генерируемый код будет идентичен. Но поскольку оператор WriteLn теперь находится на отдельной строке, отладчик может интерпретировать его отдельно. Если теперь Вы будете нажимать клавишу F8, то увидите, что строка выполнения будет при выполнении цикла 10 раз возвращаться на WriteLn.
Трассировка программы
Трассировка программы во многом аналогична ее выполнению по шагам. Единственное исключение состоит в том, что когда встречается оператор вызова процедуры/функции, при трассировке эти процедуры и функции также выполняются по шагам, а при простом выполнении по шагам управление возвращается вам после завершения выполнения подпрограммы.
Например, чтобы выполнить трассировку кода в вышеприведенном примере, загрузите файл, затем выберите команду Run → Trace Into или нажмите клавишу F7. Когда Вы в первый раз делаете это, управление перемещается на оператор begin основной программы. Повторное нажатие F7 снова перемещает строку управления на оператор for. После этого нажатие клавиши F7 трассирует вызов функции Negate — строка выполнения перемещается на оператор begin в блоке функции. Если Вы продолжаете нажимать F7, строка выполнения перемещается по функции, а затем, когда Вы дойдете до оператора end, возвращается к оператору вызова.
Формат программы влияет на поведение строки выполнения при трассировке, хотя и не в такой степени как при пошаговом выполнении. Если код сформатирован как в первоначальном варианте приведенного выше примера, то трассировка оператора for приводит к выполнению 10 раз функции Negate. Если вы разобьете оператор for на две строки, то трассировка оператора end функции возвращает строку выполнения: ту строку основной программы, которая будет выполняться следующей. Первые девять раз это снова будет вызов функции. В десятый раз строка выполнения перемещается на оператор end программы.
Трассировка или выполнение по шагам?
Пошаговое выполнение и трассировка выполняют одно и то же действие, кроме того случая, когда строка выполнения находится на строке вызова процедуры/функции, или когда выполняется оператор begin в начале программы или модуля, который использует другие модули.
Выполнение begin в блоке begin..end основной программы вызывает код
инициализации для любого используемого в программе модуля в том порядке,
который указывается в операторе uses программы. Аналогично, выполнение
оператора begin в начале секции инициализации вызывает код инициализации для любых модулей, используемых в данном модуле. Выполнение по шагам и трассировка работает в этих случаях как и следовало ожидать — пошаговое выполнение begin выполняет всю инициализацию, возвращая управление на следующий оператор только после того, как все будет завершено; при трассировке выполняется трассировка кода инициализации.
Пошаговое выполнение и трассировка методов объектов
Если в программе используются объекты, отладчик ведет себя аналогично своему поведению в случае обычных процедур/функций. Пошаговое выполнение метода интерпретирует метод как один шаг, возвращая управление к отладчику после того как метод завершает выполнение. Трассировка метода загружает и выводит на экран код метода и трассирует его операторы.
Выполнение больших фрагментов
Иногда, конечно, нежелательно выполнять по шагам всю программу только для того, чтобы добраться до того места, где возникает проблема. Отладчик дает Вам возможность выполнять сразу большой фрагмент программы до той точки, где вы хотите начать выполнение по шагам.
Чтобы задать в программе точку, до которой она должна выполняться, а затем остановиться, используйте команду Run → GoTo Cursor или клавишу F4. (Этим вы сообщите отладчику, что не хотите выполнять программу по шагам, пока не достигнете заданной точки.) Установите курсор на той строке, где вы хотите возобновить управление отладкой, затем нажмите клавишу F4. Заметим, что Вы можете сделать это как в начале сеанса отладки, так и когда уже выполните часть программы по шагам или протрассируете.
Внимание: С использованием этой команды связана одна особенность: если Вы хотите, чтобы программа выполнилась до определенной строки, и устанавливаете курсор внутри модуля (Unit), то этого не произойдет, Вы просто получите ошибку Cannot Run a Unit , и этим все закончится, т.к. IDE понимает это действие, как приказ запустить модуль, чего делать нельзя. Требуется объяснить IDE, чего Вы от нее хотите примерно так: «Запусти основную программу, и только потом выполни все, до текущего положения курсора». Для этого надо зайти в меню Compile → Primary File, указать системе основной файл (НЕ модуль) Вашего приложения, и
только после этого установить курсор внутрь модуля, и нажать F4…
Казалось бы, что поменялось? А вот что: теперь IDE точно знает — основным
файлом приложения является тот, который был установлен, как Primary File,
следовательно, совершенно нет необходимости запускать МОДУЛЬ, достаточно
запустить основной файл, и остановиться тогда, когда выполнение дойдет до
нужной строки в модуле.
Что такое окно Watches и как им пользоваться?
Выполнение программы по шагам или ее трассировка могут помочь Вам найти ошибки в алгоритме программы, но обычно желательно также знать, что происходит на каждом шаге со значениями отдельных переменных. Можно, конечно, по-старинке добавлять в необходимые места программы оператор WriteLn, который распечатает значение контролируемой переменной (а иногда просто нет другого выбора, например, при компиляции крупных проектов на Турбо Паскале возникает необходимость вообще отказаться от IDE, и пользоваться автономной версией компилятора — TPC — запускаемой из командной строки), но если уж есть возможность пользоваться средой программирования — то лучше использовать для контроля за переменными одно из специальных средств IDE: окно Watches (Просмотр) или диалоговое окно Evaluate and Modify (Вычисление и модификация).
Оба средства вычисления и просмотра работают на уровне выражений, поэтому важно определить, что считается выражением. Выражение состоит из констант, переменных и структур данных, скомбинированных с помощью операций и большинства встроенных функций. Почти все, что вы можете использовать в правой части оператора присваивания, может также использоваться в качестве отладочного выражения.
Элементы выражений отладчика
┌────────────────┬────────────────────────────────────────────────────┐ │Элемент │Допустимые значения │ │выражения │ │ ├────────────────┼────────────────────────────────────────────────────┤ │ │Все допустимые типы: Boolean, Byte, Char, │ │Константы │перечислимый тип, Integer, Longint, Real, Shortint, │ │ │Word и строковый тип. │ ├────────────────┼────────────────────────────────────────────────────┤ │Переменные │Все типы, включая типы, определенные пользователем. │ ├────────────────┼────────────────────────────────────────────────────┤ │ целочисленный│Любое целочисленное выражение с переменными │ │тип │границами диапазона. │ ├────────────────┼────────────────────────────────────────────────────┤ │ тип с │Любые выражения с плавающей точкой или целочисленные│ │плавающей точкой│выражения; лишние значащие цифры отбрасываются. │ ├────────────────┼────────────────────────────────────────────────────┤ │ │Любое символьное выражение, включая печатаемые │ │ символьный │символы в одинарных кавычках, целочисленные │ │тип │выражения, тип которых приведен к типу Char, и │ │ │контанты ASCII (#xx). │ ├────────────────┼────────────────────────────────────────────────────┤ │ булевский тип│True, False и все булевские выражения. │ ├────────────────┼────────────────────────────────────────────────────┤ │ перечислимый │Любые совместимые перечислимые константы или │ │тип │целочисленные выражения в рамках диапазона, тип │ │ │которых приведен к совместимому перечислимому типу. │ ├────────────────┼────────────────────────────────────────────────────┤ │ │Любые совместимые указатели или выражения с │ │ указатель │приведенными к ним типами; функция Ptr с │ │ │соответствующим параметрами. │ ├────────────────┼────────────────────────────────────────────────────┤ │ │Любая строковая константа (текст в одинарных │ │ строковый тип│кавычках); строковые переменные; строковые │ │ │выражения, состоящие из конкатенированных строковых │ │ │констант и переменных. │ ├────────────────┼────────────────────────────────────────────────────┤ │ │Любая множественная константа; любое выражение, │ │ множество │совместимое с множественным типом, в котором │ │ │используются операции +, - и *. │ ├────────────────┼────────────────────────────────────────────────────┤ │Приведение типа │Соблюдаются стандартные правила Паскаля. │ ├────────────────┼────────────────────────────────────────────────────┤ │Операции │Все операции Borland Pascal. │ ├────────────────┼────────────────────────────────────────────────────┤ │Встроенные │Все функции, допустимые в выражениях-константах. │ │функции │ │ ├────────────────┼────────────────────────────────────────────────────┤ │Массивы │Массивы Borland Pascal - Mem, MemL, MemW. │ └────────────────┴────────────────────────────────────────────────────┘
Разберем использование окна Watches
Вначале это окно нужно отобразить на экране. Делается это выбором пункта
меню Debug → Watch. На экране появится пустое окно с соответствующим заголовком.
Теперь запускаем программу в пошаговом режиме (нажатием клавиши F7, или
выбором меню «Run → Trace Into»), в редакторе устанавливаем курсор на
название переменной, за которой будем «следить», и жмем Ctrl+F7 (или меню
«Debug → Add Watch…») и подтверждаем выбор нажатием «Ok»… Всё…
Переменная добавлена в окно Watches, и можно наблюдать за ее значением на Watch каждом шаге выполнения программы…
Примечание: Если выбрать переменную для просмотра без предварительного
отображения пустого окна Watches на экране, ничего страшного не произойдет: IDE автоматически откроет окно Watches самостоятельно.
Например, после выполнения выделенной строки
i := 15;
значение переменной i будет уже равно не 0, а 15…
В окне Watches могут отображаться любые типы констант/переменных, объявленных в программе. Например, если описан массив …
const arr: array[1 .. 10] of integer = ( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 );
… то можно просмотреть одновременно (!!!) как весь этот массив, так
и его левую и правую части… Для этого достаточно ввести во втором и Просмотр третьем случае не только название массива, но и стартовый элемент, и массива (через запятую) число повторений.
Кроме массивов и переменных встроенных типов возможно просматривать Просмотр также и записи (либо в простом формате — только имя переменной, либо в записи специальном — с добавлением спецификатора R.
Все возможные спецификаторы перечислены в таблице (перед любым спецификатором можно указать количество повторений, а если не нужно преобразовывать тип переменной, то сам спецификатор можно не указывать, чем я уже пользовался выше, при выводе части массива arr):
┌──────┬─────────────┬────────────────────────────────────────────────────────┐ │ │Тип, на │ │ │Символ│который он │Функция │ │ │влияет │ │ ├──────┼─────────────┼────────────────────────────────────────────────────────┤ │$, H │целочисленные│Шестнадцатиричный. Выводит целочисленные значения с │ │или X │типы │префиксом $, включая те, которые содержатся в структуре │ │ │ │данных. │ ├──────┼─────────────┼────────────────────────────────────────────────────────┤ │ │Char, │Символьный. Выводит специальные символы для кодов ASCII │ │C │строковые │0..31. По умолчанию такие символы выводятся в виде │ │ │типы │значений #xx. │ ├──────┼─────────────┼────────────────────────────────────────────────────────┤ │ │целочисленные│Десятичный. Выводят целочисленные значения в десятичном │ │D │типы │виде (включая те, которые содержатся в структурах │ │ │ │данных). │ ├──────┼─────────────┼────────────────────────────────────────────────────────┤ │Fn │с плавающей │С плавающей точкой. Выводит n значащих цифр, где n лежит│ │ │точкой │в диапазоне 2..18 (по умолчанию - 11). │ ├──────┼─────────────┼────────────────────────────────────────────────────────┤ │ │ │Дамп памяти. Выводит n байт памяти, начиная с адреса, │ │nM │все │указываемого выражением. Если n не задано, то по │ │ │ │умолчанию оно равно значению размера в байтах типа │ │ │ │переменной. │ ├──────┼─────────────┼────────────────────────────────────────────────────────┤ │P │указатели │Указатель. Выводит указатели в формате сегм:смещ (а не │ │ │ │Ptr(сегм:смещ), как это делается по умолчанию. │ ├──────┼─────────────┼────────────────────────────────────────────────────────┤ │R │записи, │Запись. Выводит имена полей, например, (X:1;Y:10; Z:5) │ │ │объекты │вместо (1, 10,5). │ ├──────┼─────────────┼────────────────────────────────────────────────────────┤ │ │ │Строки. Выводит символы ASCII 0..31 в виде #xx. │ │S │Char, строки │Использует только для модификации дампов памяти (см. │ │ │ │выше nM). │ └──────┴─────────────┴────────────────────────────────────────────────────────┘
Окно Evaluate and Modify
Но кроме простого просмотра значений той или иной переменной или выражения,
существует средство, позволяющее вам в любой момент вычислять выражения и
изменять на этапе выполнения значения переменных. Этим средством и является
диалог Evaluate and Modify (Вычисление и модификация).
Вычисление выражений
Чтобы вычислить выражение, выбираем команду Debug → Evaluate/Modify или нажимаем клавиши Ctrl+F4. Отладчик выводит диалоговое окно Evaluate and Modify (Вычисление и модификация). Здесь (в поле ввода Expression) можно занести любое допустимое выражение , или выбрать его из списка ранее вычисленных при помощи этого же диалога выражений и отредактировать.
После нажатия на Enter или щелчка мышью на кнопке Evaluate (Вычислить), текущее значение выражения будет показано в поле Result (Результат).
Примечание: если в поле Expression введено выражение, которое не может быть вычислено интегрированной средой, то в поле Result появится вот такая надпись: «Cannot evaluate this expression».
Модификация переменных
Кроме этого, во время отладки с помощью диалогового окна Evaluate and Modify существует возможность поменять значение переменной на любое другое, чтобы проверить работу программы с другим, вновь присвоенным значением переменной. Для этого нужно установить курсор на имени переменной, и выбрать в меню Debug → Evaluate/Modify… (или просто нажать Ctrl+F4)…
В появившемся окне в поле Expression (Выражение) достаточно ввести имя переменной (или ничего не делать, если имя уже введено), и нажать кнопку Evaluate… Текущее значение выбранной переменной будет отображено в поле Result. Если оно же отображается и в поле New Value, это значит, что у Вас есть возможность прямо сейчас поменять это значение на любое другое (разумеется, совместимое по присваиванию с типом выбранной переменной; присваивать строке целому числу Вам никто не позволит, также, как и, например, записать в целочисленную переменную значение 3.14159), и применить новое значение переменной, не перезапуская программу…
Например, допустим, что программа имеет вид:
var i: integer; begin for i := 1 to 20 do writeln(i); readln; end.
, и Вам захотелось попасть в точку, где распечатывается значение i = 20 (желание далеко не самое сумасшедшее, представьте, например, что вместо простого распечатывания значения i там будет вызов какой-нибудь функции, которую надо прогнать пошагово при определенном значении i, да еще и функция может быть длинной и долго выполняться), но не очень хочется нажимать F7 почти 20 раз и приходить в нужную точку «естественным путем». Что делаем? А вот что:
Добавляем значение i в окно Watches, начинаем выполнять программу пошагово (F7)… Я остановился, когда значение i было равно трем, хотя это же самое можно было сделать и сразу после входа в цикл, то есть как только i стало равно единице.
Теперь ставим курсор под название переменной i и жмем Ctrl+F4 для вызова нужного нам окна… Состояние экрана, которое должно получиться, видно на скриншоте…
Переходим в поле New Value (как я говорил, если в нем записано текущее значение переменной, то нам будет позволено его сменить), печатаем в нем значение 20, и жмем на «Modify»…
Как видим, значение i в Watches тоже поменялось на 20, теперь спокойно закрываем окно «Evaluate and Modify» (кнопкой Cancel), и продожлжаем выполнять программу пошагово…
Таким образом, мы пропустили все НЕинтересующие нас в данном случае шаги,
выполнение которых могло занять значительное время…
Окно Call Stack — что это такое?
В IDE Паскаля есть еще одно очень удобное средство отладки — просмотр стека вызовов подпрограмм. Представьте себе, что программа имеет не только основную часть, но и несколько процедур/функций, вызывающих друг друга. В таком случае при пошаговой отладке становится сложно держать в памяти, какая именно процедура вызвала ту, что выполняется сейчас, и куда, соответственно, вернется управление после завершения текущей подпрограммы.
Да и не нужно этого держать в голове. Для этого существует такое средство, как «Call Stack» (вызывается из меню Debug → Call Stack или просто Ctrl+F3). Например, пусть наша программа имеет вид:
function fact(n: longint): longint; begin if n = 0 then fact := 1 else fact := n * fact(n - 1); end; function b(n: longint): integer; begin b := 2 * fact(n); end; begin writeln( b(10) ); end.
Если начать выполнять ее пошагово, очень скоро можно запутаться в том, что именно сейчас выполняется (факториал какого числа вычисляется в данный момент, к примеру), и что еще осталось НЕзавершенным. А если программа будет в 10 раз длиннее, и будет содержать не 2, а 10 процедур/функций? В таком случае достаточно вызвать окно Call Stack (способ вызова — выше), и посмотреть, что именно в данный момент выполняется (то есть находится на першине стека вызовов), и что еще выполняться будет (находится ниже в списке), вплоть до Program, обозначающего, самый нижний уровень — основную программу…
Вот, например, в данном случае: выполняется функция вычисление факториала 8, которая вызвана из нижестоящей в списке функции вычисления факториала 9, которая в свою очередь… Ну, дальше все понятно… При продолжении пошагового выполнения этой программы в окно Call Stack будут добавляться новые и новые вызовы Fact (7), Fact(6), … до Fact(0); потом рекурсия начнет раскручиваться обратно…
Кстати, Call Stack — незаменимый помощник именно при работе с рекурсивными подпрограммами, поскольку дает возможность контролировать последовательность вызовов рекурсивной функции, и на ранней стадии определить, например, бесконечную рекурсию…
Например, здесь — совершенно очевидно, что рекурсивная функция оформлена неверно (отсутствует ветка Else), сразу после того, как в окне Call Stack появились вызовы f (-1) и f(-2)…
Еще одно полезное применение окна Call Stack — если вы случайно начали трассировку кода, который хотели бы выполнить за один шаг. В стеке вызовов вы можете найти тот вызов, который начали трассировать по ошибке, затем выбрать команду Run to Cursor, чтобы выполнить за один шаг остальную часть вызова.
Что такое точки останова программы?
Кроме всех вышеперечисленных возможностей, значительно облегчающих жизнь программисту, в IDE Паскаля встроено еще одно средство, очень мощное и эффективное (при правильном использовании)… Это — работа с точками останова программы (BreakPoints).
Точка останова — это обозначенная в коде программы позиция, в которой вы хотите прекратить выполнение программы и вернуть выполнение отладчику. В этом смысле точка останова работает аналогично команде GoTo Cursor, при которой программа выполняется обычным путем до достижения определенной точки. Основное различие состоит в том, что вы можете задать несколько точек останова и точки останова, которые будут срабатывать не при каждом их достижении.
Допустим, есть следующая программа:
const parameter = 10; function f(x: integer): integer; begin f := 10 * parameter - sqr(x); end; var i, j: integer; arr: array[1 .. 20] of real; begin for i := 1 to 20 do begin j := f(i); arr[i] := (15 * j / parameter) + i / j - 8; end; { ... } end.
(не обольщайтесь, программа может быть не в 17, а в 1700 строк длиной, и функция f может быть гораздо более сложной, так же как и способ ее вызова)…
Естественно, запустив эту программу, получаем:
Runtime error 200 at 0006:0004.
, из чего заключаем, что где-то в программе происходит деление на 0. Ну, где
оно происходит, понятно. А вот на какой итерации? Чему равно i, при котором
происходит эта ошибка? Можно, конечно, воспользоваться старым и проверенным
способом, и сделать так:
const parameter = 10; function f(x: integer): integer; begin f := 10 * parameter - sqr(x); end; var i, j: integer; arr: array[1 .. 20] of real; begin for i := 1 to 20 do begin j := f(i); writeln('j = ', j); arr[i] := (15 * j / parameter) + i / j - 8; end; { ... } end.
, после чего нам будут распечатаны все значения j, для которых программа отработала нормально, и еще одно, при котором как раз и произошло «Деление на Ноль». Но для этого нужно вносить изменения в программу. А можно обойтись без её изменений… Используя точку останова…
Для этого проделаем следующее… Во-первых, добавим переменную i в список Watches, так как нам нужно найти именно «при каком i программа вылетает».
Далее — установим курсор на той строке программы, где происходит деление, и выберем в меню пункт «Debug → Add Breakpoint…» Экран примет вид, показанный на снимке справа.
Примечание: строка, на которую устанавливается BreakPoint, должна содержать выполняемый код и не может быть комментарием, описанием или пустой строкой…
В поле Condition внесем условие, при котором следует остановить программу (условие вводится так же как и при использовании условных операторов в программе, только Условный If здесь присутствовать не должно), и подтверждаем установку BreakPoint-а нажатием кнопки «Ok»:
Строка, в которой установлен хотя бы один BreakPoint (а устанавливать можно несколько точек останова для программы, причем даже на одной строке, но с разными условиями, может быть установлено более одного BreakPoint-а) меняет цвет на красный…
Если теперь запустить программу (обычным способом — через Ctrl+F9, или пошагово, не имеет значения), то как только значение j в Условный выделенной строке станет равным 0, прогон программы будет приостановлен с выдачей вот такого сообщения:
Как видим (в окне Watches), происходит это при i = 10… Что и требовалось
определить…
Чтобы просмотреть, какие BreakPoint-ы были установлены в программе, достаточно зайти в меню «Debug → BreakPoints», и будет выведен список всех точек останова для данной программы:
Нажатием на «Clear All» можно удалить все точки останова сразу, «Delete» удалит только подсвеченный BreakPoint, а «Edit»-ом можно отредактировать текущий (подсвеченный) BreakPoint — подкорректировать условие, поменять номер строки, в которой должна производиться проверка, изменить счетчик числа проходов (задание для точки останова счетчика проходов сообщает отладчику, что останавливать программу нужно не при каждом достижении точки останова, а только на n-ый раз. То есть, если счетчик проходов равен 3, то отладчик останавливает программу только при третьем достижении данной точки останова) и т.д.
Поиск нужного места
IDE предусматривает два способа поиска в программе заданного места. Простейший способ предоставляет команда Find Procedure (Поиск процедуры) из меню Search. Эта команда запрашивает у Вас имя процедуры или функции, затем находит соответствующую строку в файле, где определяется эта подпрограмма. Этот подход полезно использовать при редактировании, но его можно комбинировать с возможностью выполнения программы до определенной точки, чтобы пройти программу до той части кода, которую вы хотите отладить.
Повторное выполнение (сброс программы)
В ходе сеанса отладки иногда желательно начать все сначала. Выберите команду Run → Reset Program или нажмите клавиши Ctrl+F2. Это приведет к полному сбросу, так что выполнение по шагам, или трассировка начнется в начале основной программы.
Отслеживание вывода программы
При выполнении программы по шагам часто полезно просмотреть вывод программы, называемый экраном пользователя. IDE предоставляет несколько способов просмотра экрана пользователя.
Переключение экранов
В любой момент сеанса отладки вы можете выполнять переключение экрана IDE и экрана пользователя. Чтобы вывести экран пользователя, нажмите клавиши Alt+F5. Чтобы вернуться в IDE, нажмите любую клавишу или щелкните «мышью».
Окно Output
IDE для DOS предусматривает для экрана пользователя окно, которое называется окном вывода. Выбрав команду меню Debug → Output, вы можете открыть (вывести на передний план) активное окно, содержащее вывод программы. Настроить размер этого окна можно аналогично окну редактирования.
Введение.
Turbo
Pascal предлагает сверхусовершенствованную
среду, с автоматическим управлением
проектом, модульной организацией
программ, высокой скоростью компиляции,
с легко используемыми оверлеями. Но
даже используя все эти предоставленные
средства, программы пользователя могут
содержать ошибки, которые приводят к
неправильной работе программы.
В
помощь пользователю Turbo Pascal предоставляет
средства, необходимые для отладки его
программы, способствующие устранению
всех ошибок в программе, ее тщательному
тестированию и выполнению. Turbo Pascal
позволяет легко определять местоположение
ошибок во время компиляции и во время
выполнения программы, а также позволяет
включать или выключать автоматический
контроль ошибок во время выполнения
программы.
Особенно
важно то, что Turbo Pascal имеет мощный и
гибкий отладчик исходного уровня,
который позволяет пользователю выполнять
программу построчно, просматривать
выражения и модифицировать переменные
по мере необходимости. Отладчик встроен
в интегрированную среду разработки
(IDE) Turbo Pascal; пользователь может
редактировать, компилировать и отлаживать
программу даже не выходя из Turbo Pascal. Для
больших или сложных программ, которые
требуют использования всего диапазона
средств отладки от машинного языка до
вычисления выражений Паскаля, Turbo Pascal
полностью поддерживает автономный
отладчик фирмы Borland, Turbo Debugger.
Типы
ошибок.
Существует
три основных типа программных ошибок:
ошибки времени компиляции, ошибки
времени выполнения и логические ошибки.
Ошибки
компиляции.
Ошибки
компиляции или синтаксические ошибки
встречаются, когда забывают объявить
переменную, передают ошибочное количество
параметров процедуры, при назначении
действительного значения целочисленной
переменной. Это означает, что записываются
операторы, которые не согласуются с
правилами Паскаля.
Turbo
Pascal не закончит процесс компиляции
программы пользователя (генерацию
машинного кода), пока все синтаксические
ошибки не будут удалены. Если Turbo Pascal
обнаружит синтаксическую ошибку во
время компиляции программы, он
останавливает компиляцию, входит в
исходный текст, указывает местоположение
ошибки позиционированием курсора и
выводит сообщение об ошибке в окно Edit.
Как только пользователь исправит ошибку,
он сможет начать процесс компиляции
снова.
Если
используется версия командной строки
(TPC.EXE), Turbo Pascal будет выводить ошибочный
оператор, номер строки и сообщение об
ошибке. Затем пользователь может войти
в любой используемый им редактор, найти
заданную строку, исправить ошибку и
перекомпилировать программу. Для
дополнительной информации о сообщениях
об ошибках см. Приложение А в Руководстве
программиста.
Ошибки
времени выполнения.
Другой
тип ошибок — ошибки времени выполнения
программы или семантические ошибки.
Они встречаются, когда пользователь
компилирует синтаксически корректную
программу, которая пытается сделать
что-нибудь запрещенное во время ее
выполнения, например, открывает
несуществующий файл для ввода или
производит деление на 0. В этом случае
Turbo Pascal выводит на экран следующее
сообщение об ошибке: Runtime error ## at seg:ofs
(Ошибка выполнения # в сегменте:смещение)
и останавливает выполнение программы
пользователя.
При
использовании интегрированной среды
Turbo Pascal определяет местоположение ошибки
выполнения автоматически, осуществляя
переход в окно редактирования для
соответствующего исходный файл.
Если
пользователь выполняет программу в
среде MS-DOS, он будет возвращаться в
MS-DOS. Пользователь может загрузить модуль
TURBO.EXE и использовать опции Search/Find error
для локализации позиции ошибки в исходной
программе (убедитесь, что опция Destination
установлена в Disk). Для обнаружения ошибки
пользователь может также использовать
и опцию /F для компилятора командной
строки (TPC.EXE).
(Более
полное объяснение опций командной
строки TPC.EXE приведено в главе 9 «Компилятор
командной строки».)
Логические
ошибки.
Программа
пользователя может содержать и логические
ошибки. Это означает, что программа
делает то, что ей указали вместо того,
что хотелось бы. Может отсутствовать
инициализация переменной; могут оказаться
ошибочными вычисления; рисунки,
изображенные на экране, выглядят
неправильно; программа может просто
работать не так, как было задумано. Такие
ошибки находятся с большим трудом, и
интегрированный отладчик поможет вам
в этом случае наилучшим образом.
Интегрированный
отладчик Turbo Pascal.
Некоторые
ошибки времени выполнения (логические
ошибки) незаметны и трудны для
прослеживания. Другие ошибки могут
скрываться за неуловимым взаимодействием
разделов большой программы. В этих
случаях необходимо интерактивное
выполнение программы, во время которого
производится наблюдение за значениями
определенных переменных или выражений.
Вам хотелось бы, чтобы Ваша программа
останавливалась при достижении
определенного места так, чтобы просмотреть,
как она проработала этот кусок. Вам
хотелось бы остановиться и изменить
значения некоторых переменных во время
выполнения программы, изменить
определенный режим или проследить за
реакцией программы. И вам хотелось бы
сделать это в режиме, когда возможно
быстрое редактирование, перекомпилирование
и повторное выполнение программы.
Интегрированный
отладчик Turbo Pascal имеет все описанные
выше возможности и даже более того. Он
представляет собой встроенную часть
интегрированной усовершенствованной
среды Turbo Pascal (IDE): для использования
предлагаются две основные функции меню
(Run, Debug), а также некоторые клавиши для
команд отладчика. Для дополнительной
информации об IDE горячих клавишах см.
главу 7 «Справочник по IDE» или
справочную информацию о Turbo Pascal.
Что
может делать отладчик.
Интегрированный
отладчик работает очень просто. Ему не
требуются специальные инструкции в
Вашем коде, он не увеличивает размер
Вашего .EXE файла и не требует перекомпиляции
для создания отдельного .EXE файла после
окончания отладки.
Если
Ваша программа разделена на ряд модулей,
исходный код каждого из них автоматически
загружается в редактор при трассировке.
Если
Вы используете оверлеи, отладчик
автоматически обрабатывает их внутри
IDE, которая выполняет переключения между
компилятором, редактором и отладчиком.
Обзор
возможностей отладчика:
Трассировка.
F7
Run/Trace
Into Вы можете выполнить одну строку вашей
программы, затем прерваться и посмотреть
на результаты. При вызове процедуры или
функции внутри вашей программы, Вы
можете задать режим выполнения вызова
как одного шага или режим трассировки
этой процедуры или функции строка за
строкой.
Вы
можете так же трассировать вывод Вашей
программы строка за строкой. Вы можете
так же установить, чтобы экран переключался
по необходимости или использовать два
монитора. Вы можете так же установить
экран вывода в отдельном окне.
Переход
на курсор. F4
Run/Go
to Сursor Вы можете передвинуть курсор на
определенную строку в Вашей программе,
а затем указать отладчику выполнить
программу до достижения этой строки.
Это позволяет обходить циклы или другие
утомительные участки программы, это
также позволяет перебираться в то место
программы, откуда Вы хотите начать
отладку.
Прерывание.
С
помощью команды Debug/Breakpoints Вы можете
пометить строки в Вашей программе как
точки прерывания. Когда в процессе
выполнения Вашей программы достигается
точка прерывания, выполнение программы
приостанавливается и отображается
исходный текст и курсор останавливается
на строке с точкой прерывания. Затем Вы
можете проверить значения переменных,
начать трассировку или выполнить
программу до другой точки прерывания.
Вы можете подключить условие к точке
прерывания. Вы можете также прерваться
в любой точке Вашей программы, нажав
клавишу Ctrl-Break. Произойдет остановка на
следующей строке исходной программы,
как если бы в этой строке была установлена
точка прерывания.
Наблюдение.
Debug/Watches
Пользователь имеет возможность задавать
для просмотра в окне Watch некоторые
объекты (переменные, структуры данных,
выражения). Просматриваемые данные
меняются, отражая текущие изменения в
программе при пошаговом выполнении.
Вычисление/модификация
Ctrl-F4.
Debug/Evaluate/Modify
Пользователь может вызвать окно Evaluate,
что проверить значения переменных,
структуру данных и выражения в
интерактивном режиме. Используя окно
Evaluate, Вы можете изменить значение любой
переменной, включая строки, указатели,
элементы массива и поля записей. Это
обеспечивает простой механизм для
проверки, как Ваш код реагирует на
определенную установку значений или
условий.
Поиск.
Пользователь
может быстро находить объявления
процедур или функций, даже если программа
разбита на несколько модулей (Search/Find
Рrocedure). Во время трассировки Вы можете
быстро вернуться обратно из вызовов
процедур или функций и проверить
параметры каждого вызова (Window/Call Stack).
Подготовка
к использованию отладчика.
До
начала отладки Вы должны понимать, что
основным элементом выполнения в отладчике
является строка, а не оператор. Более
точно наименьшим элементом выполнения
является строка. Если на одной строке
находится несколько операторов, они
будут выполняться вместе при нажатии
F7. С другой стороны, если один оператор
размещен на нескольких строках, то при
нажатии F7 будет выполняться весь
оператор. Все команды выполнения
основываются на строках, включая
пошаговую отладку и точки прерывания;
строка, на которой находится выполнение,
всегда отмечена курсором выполнения.
Прежде,
чем начать отладку программы, Вы должны
задать для компилятора Turbo Pascal инструкцию
по генерации таблицы символов и таблицы
номеров строк этой программы. Таблица
символов представляет собой небольшую
базу данных со всеми используемыми
идентификаторами — константами, типами,
переменными, процедурами и информацией
о номерах строк. Директивы компилятора
$D+ и $L+ делают это по умолчанию; они
соответствуют элементам меню
Options/Compiler/Debug
Information и
Options/Compiler/Local Symbols. Так
же по умолчанию установлена опция
Options/Debugger/Integrated, которая генерирует
отладочную информацию в выполнимом
файле.
Директива
{$D+} генерирует таблицу номеров строк,
которая устанавливает соответствие
между объектным кодом и исходным модулем.
Директива {$L+} генерирует локальную
отладочную информацию, а именно, строит
список идентификаторов, локальных для
каждой процедуры или функции, для того,
чтобы отладчик мог хранить информацию
о них в процессе отладки. Когда Вы
используете директивы компилятора,
разделяйте их запятыми и без пробелов,
и ставя $ только перед первой директивой;
например {$D+,L+}.
Примечание:
Вы можете отключить эти переключатели
для сохранения памяти или дискового
пространства во время компиляции.
Когда
Вы выполняете пошаговую отладку, Turbo
Pascal будет иногда переключаться на экран
пользователя, выполнять Ваш код, а затем
возвращаться в интегрированную среду,
ожидая следующей команды. Вы можете
управлять переключением экрана с помощью
установок Options/Debugger/Display Swapping, которые
могут принимать 3 значения:
-
Smart:
Это режим по умолчанию. Среда IDE
переключается на экран пользователя,
когда программа обращается к видеопамяти
или при вызове программы. -
Always:
Переключение на экран пользователя
происходит на каждом шаге. -
None:
Переключение экранов не происходит.
Интегрированная среда остается видимой
все время. Если в программе предусматривается
вывод на экран или требуется ввод
информации, текст будет писаться на
экране среды. Вы можете восстановить
окна интегрированной среды, выбирая
Ё/Refresh Display.
Начало
сеанса отладки.
Наиболее
быстрый способ начать отладку состоит
в загрузке программы и выборе команды
Run/Trace Into (F7). Программа будет компилироваться.
Когда компиляция завершится, редактор
отобразит на дисплей тело основной
программы с индикацией строки выполнения
на первом операторе begin. Пользователь
может начать трассировку программы с
этого места (нажать клавиши F7 или F8) или
использовать другие методы которые
приведены ниже.
Если
пользователю необходимо начать отладку
с определенного места программы, он
может выполнить программу до этого
места, а затем остановиться. Для этого,
загрузите нужный раздел исходного
модуля в редактор и передвиньте курсор
на строку, где Вы желаете остановиться.
Затем можно поступить двумя способами:
-
—
Выбрать команду Run/Goto Cursor (или нажать
клавишу F4), которая будет выполнять
программу пользователя до достижения
строки, помеченной курсором, а затем
останавить работу программы. -
—
Задать на указанной строке точку
прерывания (выбрать команду Debug/Toggle
Breakpoint или нажать на Ctrl-F8), затем выполнить
программу (выполнить команду Run/Run или
нажать Ctrl-F9); остановка будет происходить
каждый раз при достижении заданной
строки. Вы можете задать несколько
точек прерывания, в этом случае программа
будет делать остановку всякий раз при
достижении какой-либо из этих точек.
Рестарт
сеанса отладки.
Если
в процессе отладки программы возникает
необходимость начать все сначала, то
нужно выполнить команду Program Reset из меню
Run. Система отладки повторно инициализируется,
и команда следующего шага вернет вас к
первой строке главной программы. При
этом производится закрытие всех файлов,
которые были открыты программой, очистка
стека всех вложенных программ, которые
вызывались программой, и освобождение
всего использованного пространства
кучи. Переменные программы, однако, не
будут повторно инициализированы или
подвержены модификации какого-нибудь
другого вида. (Turbo Pascal никогда не
инициализирует переменные автоматически).
Однако, начальные значения типированных
констант программы будут восстановлены.
Turbo
Pascal также предлагает рестарт, если Вы
производите какие-либо изменения в
программе во время отладки. Например,
если Вы изменяете часть программы, а
затем выбираете любую команду выполнения
(нажимаете клавиши F7, F8, F4, Ctrl-F9 и т.д.), Вы
получите сообщение : Source modified, rebuild? (Y/N)
(исходный модуль модифицирован, нужно
повторить сборку? да/нет ). Если Вы
отвечаете Y, Turbo Pascal будет перекомпилировать
программу и возобновит отладку программы
с начала. Если Вы ответите N, Turbo Pascal
предполагает, что Вы уверены в своих
действиях, и продолжает сеанс отладки
дальше. (Любые изменения в программе,
которые Вы произвели, не будут влиять
на ее выполнение до тех пор, пока Вы не
перекомпилируете программу). Если Вы
добавили или удалили строки программы,
курсор выполнения не реагирует на эти
изменения, и может оказаться, что будет
выделяться ошибочная строка.
Окончание
сеанса отладки.
В
процессе отладки программы Turbo Pascal
хранит трассу того, что Вы делаете и где
находитесь в данный момент. Так как
пользователь может в процессе отладки
загружать и даже редактировать различные
файлы, Turbo Pascal не интерпретирует загрузку
другого файла в редактор, как конец
сеанса отладки. Поэтому, если вы желаете
выполнить или отладить другую программу,
нужно выполнить команду Run/Program Reset
(клавиша Ctrl -F2).
Трассировка
Вашей программы.
Простейшая
техника отладки — это пошаговая отладка,
которая трассирует внутри процедур и
функций. Загрузите программу RANGE.PAS в
Turbo Pascal.
{$D+,L+}
{Для
того, чтобы обеспечить
полную
генерацию отладочной информации}
{$R-}
{Для того, чтобы отключить проверку
диапазона}
program
RangeTest;
var
List:array
[1..10] of integer;
Indx:integer;
begin
for
Indx:=1 to 10 do List[Indx]:=Indx;
Indx:=0;
while
(Indx < 11) do
begin
Indx:=Indx+1;
if
List[Indx]>0 then
List[Indx]:=-List[Indx]
end;
for
Indx:=1 to 10 do writeln(List[Indx]);
end.
Начните
отладку, нажав клавишу F7. Это пошаговая
команда. Turbo Pascal произведет компиляцию
автоматически, а затем подготовится к
пошаговой обработке этой программы.
Заметим, что курсор выполнения расположен
на операторе begin (строка 7). Помните, что
курсор выполнения помечает следующую
строку программы, которая должна быть
выполнена.
Нажмите
клавишу F7 несколько раз. Курсор выполнения
переместится на оператор List[Indx]:=Indx и
остановится. Это значит, что строка
выполняется в цикле.
Выберите
команду Debug/Watches/Add Watch (Ctrl-F7) для просмотра
в окне Add Watch. Вы можете просматривать
значения переменных, структур данных
или выражений в окне Watch.
То,
что появится в окне Add Watch зависит от
того, где располагается курсор, когда
Вы нажимаете на клавишу Ctrl-F7. Если курсор
расположен на первой букве любой
алфавитно-цифровой строки, внутри строки
или сразу за ней, строка будет копироваться
в окно Add Watch и подсвечиваться. Так, если
курсор был спозиционирован на слове
Indx, то Indx появится в окне. Если в окне
необходимо что-либо изменить, начните
набор на клавиатуре и первоначальное
выражение и подсветка исчезнут.
Как
только появится окно Add Watch, независимо
от его содержимого, можно добавить в
него текст, если нажать клавишу Ў (которая
копирует дополнительный текст из
редактора). Поместите List в окно, используя
Ў, и нажмите Enter. Тогда в окне Watch в нижней
части экрана появится строка:
List
: (1,2,0,0,0,0,0,0,0,0)
Cнова
нажмите клавишу Ctrl-F7, наберите слово
Indx и нажмите Enter. Indx будет первым в списке
в окне Watch:
Indx
: 3
List
: (1,2,0,0,0,0,0,0,0,0)
Нажмите
клавишу F7 снова и Вы увидите, что значения
Indx и List в окне Watch изменятся, отражая
работу Вашей программы.
Как
только Вы войдете в цикл while, Вы снова
увидите, что значения Indx и List изменяются
шаг за шагом. Заметим, что эти изменения
в окне Window отражают действия каждой
строки цикла после нажатия клавиши F7.
Продолжайте
нажимать на клавишу F7, пока не достигнете
начала цикла while, c Indx равным 10. Во время
прохождения через цикл, Вы можете
наблюдать как изменяются значения в
окне Watch. Когда выполняется оператор
List
[ Indx ] := — List [ Indx ];
значение
Indx изменится на -11. Если Вы продолжаете
нажимать на F7, то обнаружится, что вы
вошли в бесконечный цикл.
Таким
образом, если Вы наберете такую программу,
она будет компилироваться и выполняться.
Получается бесконечный цикл, так как
цикл while выполняется 11 раз, а не 10, и
последнее значение переменной Indx равно
11. Так как массив List содержит только 10
элементов, значение List(11) будет указывать
на некоторую позицию памяти вне массива
List. Из-за способа распределения переменных
уже окажется, что значение List(11) займет
в памяти тоже место, что и переменная
Indx. Это значит, что при Indx=11, запись:
List
[Indx] := — List [Indx]
идентична
записи
Indx
:= -Indx.
Так
как значение переменной Indx равно 11, этот
оператор изменит ее значение на -11. В
результате в программе начнется повторное
выполнение цикла. Этот цикл теперь
изменяет дополнительные байты в месте,
соответствующем List[-11..0]. И т.к. значение
Indx никогда не будет заканчивать цикл
со значением большим или равным 11, то
цикл никогда не закончится.
Важно
отметить то, что используя лишь две
клавиши (F7 и Ctrl — F7), через несколько
минут, Вы быстро и легко прослеживаете
промежуточные значения переменных и
находите ошибку.
Пошаговое
выполнение программы.
Различие
между командами Trace Into (F7) и Step Over (F8) в
том, что при использовании F7 осуществляется
трассировка внутри процедур и функций,
в то время как использование F8 приведет
к обходу вызовов подпрограмм. Эти команды
имеют особое значение при выполнении
оператора begin основной программы, если
программа использует модули, имеющие
раздел инициализации. В этом случае,
использование F7 приведет к трассировке
раздела инициализации каждого модуля,
что позволяет увидеть, что инициализируется
в каждом модуле. При использовании F8
эти разделы не будут трассироваться, и
курсор выполнения переходит на следующую
строку после begin.
Рассмотрим
следующий (неполный) пример программы:
($D+,L+)
program
TestSort;
const
NLMax=100;
type
NumList=array[1..NLMax]
of integer;
var
List
: NumList;
I,Const
: word;
procedure
Sort ( var L:NumList; Cnt:Integer);
begin
(sort
the list) (сортировка
списка)
end;
(of proc sort) (процедуры
Sort)
begin
randomize;
Count:=NLMax;
for
I:=1 to Count do
List[I]
:= Random(1000);
sort(List,Count);
for
I:=1 to Count do
Write(List[I]
:8);
Readln
end.
{программы
TestSort}
Предположим,
что Вы отлаживаете процедуру Sort. Вы
хотите осуществить трассировку процедуры
Sort, включая проверку значения внутри
List до вызова Sort. Однако, выполнять 100 раз
инициализацию внутри List очень утомительно.
Есть ли способ выполнять цикл, не
останавливаясь на каждой выполняемой
строке.
Да,
фактически, существует несколько
способов. Во-первых, Вы могли бы выделить
этот цикл в отдельную процедуру и нажать
клавишу F8 для того, чтобы обойти ее
трассировку, но это слишком нерационально.
Во-вторых, Вы могли бы установить внутри
программы точку прерывания. Мы объясним,
что это за точки прерывания, и как они
используются немного позже. В конце
концов, Вы могли бы использовать команду
Run/Go to Cursor (F4). Переместите курсор на
строку с вызовом Sort, а затем нажмите на
клавишу (F4). Ваша программа будет
выполняться до достижения строки,
помеченной курсором. Курсор выполнения
переместится на эту строку; затем Вы
можете начать трассировку с этого места,
нажимая на клавишу F7, для того, чтобы
можно было сделать трассировку внутри
Sort.
Команда
Run/Goto Cursor (F4) действует на вложенных
уровнях вызовов подпрограмм, даже если
их исходный код находится в другом
файле. Например, Вы могли бы разместить
курсор где-либо внутри процедуры Sort и
нажать на клавишу F4; программа выполнялась
бы до этой строки. По существу, Sort могла
бы быть выделена в отдельный модуль,
отладчик бы уже знал, когда нужно
остановиться и что отобразить.
Существуют
три случая, когда команда Go to Cursor (F4) не
будет выполнять программу до отмеченной
курсором строки.
Первый,
когда Вы расположили курсор между двумя
выполняемыми строками; например, на
пустой строке или строке с комментариями.
В этом случае программа будет выполняться
до следующей строки, содержащей оператор,
который может быть выполнен.
Второй
случай, когда курсор расположен вне
процедурного блока, например, на операторе
объявления переменной или операторе
program. Отладчик будет выводить сообщение
«no code generated for this line» (для этой строки
код не генерируется).
Третий
случай, когда Вы располагаете курсор
на строке, которая никогда не выполняется.
Например, строка располагается выше
курсора выполнения (предполагается,
что вы находитесь не в цикле) или строка
является частью else — условного оператора,
когда выражение if имеет значение true. В
этом случае отладчик будет действовать
так, как если бы выполнялась команда
Run/Run (Ctrl-F9); программа будет выполняться
до конца или до точки прерывания.
Предположим,
что Вы трассируете процедуру Sort,затем
хотите завершить работу программы и
посмотреть выходные результаты. Каким
способом сделать это? Сначала нужно
переместить курсор к последнему оператору
end основной части программы, а затем
выполнить команду Run/Go to Cursor (F4). Или
проще, нужно выполнить команду Run/Run
(Ctrl-F9). Она позволяет отладчику продолжить
нормальное выполнение программы
пользователя. Программа будет выполняться
до конца, или до тех пор, пока Вы не
достигнете точки прерывания или не
будет нажат Ctrl-Break.
Использование
точек прерывания.
Точки
прерывания являются важным инструментом
отладки. Точка прерывания подобна знаку
остановки, введенному в программу
пользователя. Когда программа встречает
такую точку, она останавливает свое
выполнение и ожидает дальнейших
отладочных инструкций.
Примечание:
Вы можете иметь до 16 активных точек
прерывания.
Заметим,
что точки прерывания существуют только
во время сеанса отладки; они не сохраняются
в файле .EXE, если программа компилируется
на диск. Чтобы задать точку прерывания,
используйте обычные команды редактирования
для перемещения курсора на каждую строку
программы, где Вы хотите сделать паузу.
Каждый раз выполняйте команду Debug/Toggle
Breakpoint (Ctrl-F8). Когда строка отмечается
как точка прерывания, она высвечивается.
Это не должна быть пустая строка,
комментарии, директивы компиляции;
объявления констант, типов, меток,
переменных; заголовком программы,
модуля, процедуры или функции. Как только
Вы задали точки прерывания, выполняйте
программу с помощью команды Run/Run (клавиша
Ctrl-F9). Сначала программа будет выполняться
нормально. Когда встретится точка
прерывания, программа остановится.
Соответствующий исходный файл (основная
программа, модуль или включенный файл)
загружается в окно Edit, которое
визуализируется на экране и курсор
выполнения помещается на строку с точкой
прерывания.
Заметим,
что точка прерывания не высвечивается,
когда на ней находится курсор выполнения.
Если какие-либо переменные или выражения
были добавлены в окно Watch, то они также
выводятся на дисплей со своими текущими
значениями.
Затем,
пользователь может использовать любой
режим отладки.
-
Вы
можете осуществлять пошаговое выполнение
программы, используя команду Run / Trace
Into, Step Over или Go to Cursor (F7, F8 или F4). Вы можете
проверить или изменить значения
переменных. -
Вы
можете добавить или удалить выражения
из окна Watch. -
Можно
назначить или удалить точки прерывания. -
Можно
просмотреть выходные результаты
программы, используя команду Windows/User
Screen (Alt-F5). -
Вы
можете перезапустить программу сначала
( Run/Program Reset и, затем, команду пошагового
выполнения). -
Можно
продолжить выполнение до следующей
точки прерывания (или до конца программы),
выполнив команду Run/Run (Ctrl-F9).
Для
удаления точки прерывания из строки
переместите курсор на данную строку и,
выполнив команду Debug/Toggle Breakpoint (или
нажмите Ctrl-F8) еще раз. Эта команда включает
или отключает точку прерывания в строке;
если она используется для строки с
точкой прерывания, то строка становится
нормальной.
Давайте
вернемся к примеру, который был рассмотрен
ранее.
begin
{основная часть программы Test.Sort}
Randomize;
Count
:= NLMax;
for
I := 1 to Count do
List
[I] := Random (1000);
Sort
( List,Count );
for
I := 1 to Count do
Write
( List [I] : 8 );
Readln
end.
{программа
Test.Sort}
Как
уже говорилось, идея была в том, чтобы
обойти первоначальный цикл и начать
трассировку с вызова процедуры Sort. Новый
вариант. Передвиньте курсор на строку
с вызовом процедуры и выполните команду
Debug/Toggle Breakpoint ( Ctrl-F8), которая отметит
строку, как точку прерывания. Теперь
выполните программу до этой точки,
используя команду Run/Run (Ctrl-F9 ). Когда
программа достигнет этой строки, она
остановится и позволит Вам начать
отладку.
Использование
Ctrl-Break.
Кроме
назначения точек прерывания, пользователь
может сделать немедленную остановку
во время выполнения программы, используя
клавишу Ctrl-Break. Это означает, что можно
прервать работу программы в любое время.
Когда Вы нажимаете на клавишу Ctrl-Break,
выполнение программы прекращается. Вы
возвращаетесь в редактор, курсор
выполнения расположен на следующей
строке программы, и программа готова к
дальнейшему пошаговому выполнению.
Фактически,
отладчик автоматически подключает DOS,
BIOS и другие сервисные функции. Он знает,
является ли текущий выполняющийся код
программой DOS, программой BIOS или программой
пользователя. Когда Вы нажимаете на
клавишу Ctrl-Break, отладчик ждет, пока
программа выполняется сама. Затем он
делает пошаговое выполнение инструкций
машинного уровня, пока следующая
инструкция не будет в начале строки
исходного кода на Паскале. С этого
момента отладчик прекращает работу,
перемещает курсор выполнения на эту
строку и предлагает Вам нажать на клавишу
ESC.
Примечание:
Если пользователь нажимает на клавишу
Ctrl-Break второй раз еще до того, как отладчик
находит и отображает следующую строку
исходного кода для выполнения, то
отладчик завершает работу и не пытается
найти строку исходного кода. В этом
случае, процедуры выхода не выполняются,
что означает, что файлы, видеорежим и
распределение памяти DOS могут быть не
полностью очищены.
Просмотр
значений.
Выполнение
программы предоставляет много информации,
но не в том объеме, как хотелось бы. Может
возникнуть необходимость просмотреть
за тем, как изменяются значения переменных
во время выполнения программы. Рассмотрим
процедуру Sort из предыдущей программы:
procedure
Sort ( var L : NumList; C : word );
var
Top,Min,k
: word;
Temp
: integer;
begin
for
Top := 1 to C-1 do
begin
Min
:= Top;
for
k := Top+1 to C do
if
L[k] Top then
begin
Temp
:= L[Top];
Top
:= L[Min];
L[Min]
:= Temp;
end;
end;
end;
{процедуры
Sort}
Примечание:
Измените NLMax в теле программы на 10 так,
чтобы Вы могли работать с меньшим
массивом.
В
этой процедуре есть ошибки, будем
просматривать ее (используя команду
Run/Trace Into или клавишу F7) и наблюдать за
значениями переменных L, Top, Min и k.
Отладчик
дает возможность пользователю задать
объекты для просмотра во время выполнения
Вашей программы. Как Вы и предполагаете,
объектами просмотра являются переменные,
структуры данных и выражения, расположенные
в окне Watch, где отображаются их текущие
значения, обновляемые по мере выполнения
каждой строки программы. Давайте вернемся
к предыдущему примеру. Установить
объекты наблюдения просто.
Передвигайте
курсор к каждому идентификатору и
выполняйте команду Debug/Watch/Add Watch (Ctrl -F7)
для добавления каждого выражения в окно
Watch.
Результат
может выглядеть так:
k
: 21341
Min
: 51
Top
:21383
L
: (163,143,454,622,476,161,850,402,375,34)
Предполагается,
что Вы только что вошли в процедуру
Sort, курсор выполнения расположен на
начальном операторе begin. (Если Вы еще не
вошли в процедуру Sort, то для каждого
выражения в окне Watch будет появляться
сообщение «unknown identifier» (неизвестный
идентификатор), пока Вы не войдете в
процедуру). Заметим, что переменные K,
Min и Top имеют произвольные значения, т.к.
они еще не были инициализированы.
Значения переменной L, предположительно,
тоже должно быть произвольным; они не
будут таковыми при выполнении всей
программы; все они должны быть
неотрицательными и лежать в интервале
от 0 до 999.
Если
нажать на клавишу F7 четыре раза, то мы
продвинемся к строке if L[k]Top then, назад к
вершине внешнего цикла, и снова вниз к
строке if L[k] < L[Min] then. В этот момент окно
Watch будет выглядеть следующим образом
(для L даны предыдущие значения):
k
: 3
Min
: 2
Top
: 2
L
: ( 34,143,454,622,476,161,850,402,375,34 )
Теперь
Вы можете заметить две вещи. Первое,
последнее значение переменной L(34),
которое является также и наименьшим
значением, скопировалось в первое
значение L, и значение, которое уже было
там раньше (163), исчезло. Второе, переменные
Min и Top имели одинаковые значения во
время трассировки процедуры. Фактически,
Вы можете заметить, что переменная Min
получает значение переменной Top, но она
никогда не изменяется где-либо еще.
Однако, ниже цикла располагается
проверка:
if
Min<>Top then.
Или
эта проверка ошибочна, или существует
какое-то несоответствие между этими
двумя частями процедуры. Оказывается,
ошибочна пятая строка программы. Она
должна выглядеть так:
Min
:= k, вместо L[Min] := L[k].
Исправьте
строку, переместите курсор к первоначальному
оператору begin в процедуре Sort и выполните
команду Run/Go to Cursor (F4). Так как Вы изменили
программу, на экране появится окно с
вопросом Source modified, rebild? (Y/N) (исходный
модуль модифицирован, нужна ли сборка?
Да/Нет). Ответьте Y. Программа будет
перекомпилироваться, начнется ее
выполнение, затем произойдет остановка
на начальном операторе begin процедуры
Sort. Теперь программа работает верно.
Значение первого элемента теперь не
меняется на наименьшее из значений
элементов массива L, происходит
обмен-перемещение значения первого
элемента массива на место, где до этого
располагался элемент с наименьшим
значением. Затем процесс повторяется
со второй позицией, третьей и т.д., пока
список элементов не будет отсортирован
полностью.
Паскаль
— это один из самых простых языков, но
далеко не один из самых слабых. Изучать
мы с вами будем Turbo
Pascal 7.0 —
так вот на нем можно написать любую
программу, которая придет в голову. По
возможностям он не уступает ни СИ, ни
какому другому. На Паскале можно написать
программную оболочку (типа Norton Commander),
игрушку (типа Quake) или операционную
систему (типа MS-DOS). Программы на Turbo
Pascal пишутся только для платформы MS-DOS,
но никак не зависят от конфигурации
компьютера. Главным требованием к
компьютеру является только лишь то,
чтобы он был IBM PC-совместимый, что
естественно, если на нем установлен
MS-DOS.
Особой
теории по этому языку нет, чтобы хорошо
им овладеть (тем более если это ваш
первый язык программирования) необходимо
больше практики. Этим мы и начнем
заниматься уже в этом выпуске. При этом
вам понадобиться интерпритатор Turbo
Pascal 7.0 фирмы
Borland — я говорил где его можно достать в
предыдущем выпуске. Те, кто скачал его
с моего сайта (а скачало на данный момент
73 человека) или достал где-нибудь еще,
уже смогут попрактиковаться.
При
этом я обойду стандартный подход к
изучению языков программирования, при
котором сначала начинают изучать типы
данных, используемые в языке, структуру
пограммы и все такое, а начну непосредственно
с написания программы, максимально при
этом пытаясь объяснять понятно каждый
свой ход.
Итак,
поехали…
ЧАСТЬ
5. ПРИЛОЖЕНИЯ ПРИЛОЖЕНИЕ
А.
СООБЩЕНИЯ
ОБ ОШИБКАХ
Предыдущая
страница | Следующая
страница
Сообщения об ошибках компиляции.
Приведенные ниже
списки возможных сообщений об ошибках можно получить
от компилятора при разработке программы.
Когда это возможно, компилятор будет выводить
на дисплей дополнительную диагностическую информацию в виде имени идентификатора или файла, например :
Error 15 : File not found (Window.TPU)
(Ошибка 15 : Файл не найден)
Когда ошибка
обнаружена, Turbo Pascal (в интегрированной
среде) автоматически загружает исходный файл и помещает
курсор в позицию ошибки. Компилятор командной
строки выводит на дисплей сообщение об ошибке
и ее номер, а также исходную строку
и использует знак вставки (^) для указания
места, где произошла ошибка.
Тем не менее
заметим, что некоторые ошибки обнаруживаются несколько
позже в исходном тексте. Например, несоответствие типов в операторе
присваивания не может быть обнаружено до тех пор, пока все
выражение после «:=» не будет вычислено. В таких случаях
ищите ошибку слева или выше от курсора.
1. Out of memory
(не хватает памяти)
Эта ошибка
происходит, когда компилятору не хватает памяти. Есть несколько
возможных решений этой проблемы:
— если опция
Compile/Destination имеет значение Memory, то измените ее
значение на Disk в интегрированной среде.
— если опция
Options/Compiler /Link buffer в интегрированной среде имеет значение
Memory , то измените ее значение на Disk.
В компиляторе командной строки для редактирования
на диск нужно использовать опцию /L.
— если используются
любые утилиты, находящиеся в памяти, например
SideKick и SuperKey, то их нужно удалить из памяти.
— если используется
Turbo.EXE, то постарайтесь использовать вместо Turbo.EXE TPC.EXE,
эта программа использует меньше памяти.
Если ни один вариант
не помогает, то эта программа или модуль, возможно, просто слишком
большие для компиляции в доступном объеме памяти. В этом
случае нужно разбить модуль на два или большее количество
меньших модулей.
2. Identifier expected
(ожидается идентификатор)
В этой точке
предполагался идентификатор. Возможно, Вы пытаетесь повторно объявить зарезервированное слово.
3. Unknown identifier
(неизвестный идентификатор)
Этот идентификатор
не объявлен или невидим внутри текущей сферы
действия.
4. Duplicate identifier
(дублируемый идентификатор)
Этот идентификатор
уже был использован в текущем блоке.
5. Syntax error (синтаксическая
ошибка)
В исходном тексте
был найден неправильный символ. Возможно, Вы забыли кавычки вокруг строковой
константы.
6. Error in
real constant (ошибка в константе вещественного типа)
Синтаксис констант
вещественного типа определен в главе 1
«Лексемы и константы».
7. Error in integer constant (ошибка в константе целого типа)
Синтаксис констант
целого типа определен в главе 1 «Лексемы и константы».
Заметим, что за целыми числами вещественного
типа, лежащими за пределами максимального
целого диапазона, должна следовать десятичная точка и ноль;
например :
12345678912.0
8. String constant exceeds
line (строковая константа выходит за пределы строки)
Наиболее вероятно,
что Вы забыли закрывающую кавычку в строковой константе.
9. Too many nested files
(слишком много вложенных файлов)
Компилятор допускает
не более 15 вложенных файлов. Наиболее вероятно, что
в программе более 14 вложенных файлов.
10. Unexpected end of
file (неожиданный конец файла)
Можно получить
такое сообщение об ошибке из-за следующих
причин:
— исходный файл
заканчивается перед последним end главной операторной
части. Наиболее вероятно, что количество операторов
begin и end несбалансировано.
— включенный файл заканчивается
в середине операторной части. Каждая операторная часть
должна полностью содержаться в одном файле.
— не закрыт комментарий.
11. Line too long
(строка слишком длинная)
Максимальная длина
строки равна 126 символам.
12. Type identifier
expected (ожидается тип идентификатора)
Этот идентификатор
не обозначает тип, как это должно быть.
13. Too many open
files (слишком много открытых файлов)
Если произошла
эта ошибка, то или в файле CONFIG.SYS
нет записи FILES = xx, или эта запись задает
слишком мало файлов. Увеличьте это значение до некоторого
подходящего значения, например до 20.
14. Invalid file
name (неправильное имя файла)
Неправильное имя
файла или задается несуществующий путь доступа.
15. File not found
(файл не найден)
Этот файл
не может быть найден в текущем справочнике или в любом
из поисковых справочников, которые применяются к этому типу
файла.
16. Disk full
(диск полон)
Удалите несколько
файлов или используйте новый диск.
17. Invalid
compiler directive (неправильная директива компиляции)
Буква директивы
компилятора неизвестна, один из параметров директивы
компилятора неизвестен или используется
глобальная директива компилятора, когда компиляция
тела программы уже началась.
18. Too many files (слишком
много файлов)
В компиляцию программы
или модуля включено слишком много файлов. Попытайтесь
не использовать так много файлов, например
посредством объединения включенных файлов или
укорачивания имен файлов.
19. Undefined type in
pointer definition (неопределенный тип в определении указателя)
На этот тип ранее была ссылка в объявлении типа указателя, но он не был объявлен.
20. Variable
identifier expected (ожидается идентификатор
переменной)
Этот идентификатор
не обозначает переменную, как это должно быть.
21. Error in type
(ошибка в типе)
Этот символ не
может начинать определение типа.
22. Structure
too large (структура слишком большая)
Максимальный допустимый
размер структурного типа равен 65520 байтам.
23. Set base type
out of range (базовый тип множества выходит за допустимый диапазон)
Базовый тип множества
должен быть поддиапазоном , который находится
внутри диапазона 0..255, или перечислимым типом, который имеет
не более 256 возможных значений.
24. File components may
not be files or objects (компонентами файла не могут быть файлы
или объекты)
В качестве файловых
компонент не могут быть файлы или объекты, а так же ни один из структурных
типов, которые включают тип объекта или файла.
25. Invalid string
length (неправильная длина строки)
Объявленная максимальная длина строки должна быть в диапазоне 1..255.
26. Type mismatch
(несоответствие типов)
Это может быть
по следующим причинам:
— несовместимые
типы переменной и выражения в операторе
присваивания
— несовместимые типы
фактического и формального параметра в вызове процедуры
или функции
— тип выражения,
который несовместим с типом индекса в индексации массива
— несовместимые типы
операндов в выражении.
27. Invalid subrange
base type (неправильный поддиапазонный базовый тип)
Все порядковые
типы являются допустимыми базовыми типами.
28. Lower
bound greater than upper bound (нижняя
граница больше верхней границы)
В объявлении
поддиапазонного типа нижняя граница указана
больше верхней границы.
29. Orginal type
expected (ожидается порядковый тип)
В данном случае
вещественный, строковый, структурный тип и тип указателя недопустим.
30. Integer constant
expected (ожидается целая константа)
31. Constant expected
(ожидается константа)
32. Integer or real constant
expected (ожидается целая или вещественная константа)
33. Type identifier
expected (ожидается тип идентификатора)
Этот идентификатор
не обозначает тип указателя, как это должно быть.
34. Invalid function
result type (неправильный тип результата функции)
Правильными типами
результатов функций являются все простые типы, строковые
типы и типы указателей.
35. Label identifier expected (ожидается идентификатор метки)
Этот идентификатор
не обозначает метку, как это должно быть.
36. Begin expected
(ожидается оператор begin)
37. End expected
(ожидается оператор end)
38. Integer expession
expected (ожидается целое выражение)
Предыдущее выражение
должно быть целого типа.
39. Ordinal
expession expected (ожидается выражение порядкового типа)
Предыдущее выражение
должно быть порядкового типа.
40. Boolean
expression expected (ожидается выражение булевского типа)
41. Operand types
do not match operator (типы операндов не соответствуют
оператору)
Оператор не
может быть применен к
операндам этого типа, например ‘A’ div ‘2’.
42. Error in expression
(ошибка в выражении)
Этот символ
не может участвовать в выражении
указанным способом. Возможно, Вы забыли
написать оператор между двумя операндами.
43. Illegal assignment(неправильное
присваивание)
— Файлы и
нетипированные переменные не могут быть присваиваемыми значениями.
— Идентификатору функции
можно присваивать значения только внутри операторной
части функции.
44. Field identifier
expected (ожидается идентификатор поля)
Этот идентификатор не обозначает поле в предыдущей переменной типа запись.
45. Object file
too large (объектный файл слишком большой)
Turbo Pascal не
может подредактировать .OBJ файлы, размером больше
64К.
46. Undefined
external (неопределенный внешний элемент)
Внешняя процедура
или функция не имеют соответствующего PUBLIC определения в объектном
файле. Убедитесь, что все объектные файлы заданы
в директивах {$L имя файла}
и проверьте написание идентификатора процедуры или функции
в .ASM файле.
47. Invalid object file
record (неправильная запись объектного файла)
.OBJ файл
содержит неправильную объектную запись; убедитесь, что файл фактически
является .OBJ файлом.
48. Code Segment
too large (сегмент кода слишком большой)
Максимальный размер
кода программы или модуля равен 65520
байт. Если компилируется программа, то нужно перенести
несколько процедур или функций в модуль. Если компилируется модуль,
то его нужно разбить на два или больше модулей.
49. Data segment
too large (сегмент данных слишком большой)
Максимальный размер
сегмента данных программы равен 65520 байт,
включая данные, объявленные используемыми модулями.
Если необходимо больше глобальных данных, то нужно
объявить структуры большого размера как указатели
и разместить их динамически с использованием
процедуры New.
50. Do expеcted (ожидается
ключевое слово)
51. Invalid
PUBLIC definition (неправильное определение
PUBLIC)
— Идентификатор
был сделан общедоступным с помощью директивы PUBLIC в
языке ассемблер, но он не
соответствует external объявлению в программе или в модуле на
Паскале.
— Две или более
директивы PUBLIC в ассемблере определяют один и тот же идентификатор.
— .OBJ файл определяет
PUBLIC символы , которые не находятся в сегменте CODE.
52. Invalid EXTRN
definition (неправильное определение EXTRN)
— На идентификатор
была ссылка с помощью директивы EXTRN в ассемблере,
но он не был объявлен ни в программе или модуле
на Паскале, ни в интерфейсной части используемых модулей.
— Этот
идентификатор обозначает absolute (абсолютную) переменную.
— Этот идентификатор
обозначает inline процедуру или функцию.
53. Too many EXTRN
definion (слишком много объявлений EXTRN)
Turbo Pascal не
может обрабатывать .OBJ файлы с более чем 256 объявлениями EXTRN.
54. OF expected (ожидается
ключевое слово OF)
55. INTERFACE expected
(ожидается ключевое слово interface)
56. Invalid relocatable
reference (неправильная переместимая ссылка)
— .OBJ файл содержит
данные и переместимые ссылки в сегментах, отличных
от CODE. Например,
Вы пытаетесь объявить инициализированные
переменные в сегменте DATA.
— .OBJ файл
содержит ссылки размером в байт на переместимые символы . Эта
ошибка происходит, если используются операторы HIGH и LOW с перемеcтимыми
символами или, если есть ссылка на переместимые символы в директивах
DB.
— Операнд ссылается
на переместимый символ, который не был определен ни в сегменте
CODE, ни в сегменте DATA.
— Операнд
ссылается на процедуру или функцию
EXTRN со смещением, например, CALL SortProc +8.
57. THEN expected (ожидается
ключевое слово then)
58. TO or
DOWNTO expected (ожидается ключевое слово to или downto)
59. Undefined
forward (не определен элемент, указанный ранее)
— Эта процедура
или функция была объявлена в интерфейсной части модуля,
но ее определение не встречается нигде
в части реализации.
— Эта процедура или функция
была объявлена с ключевым словом forward, но ее определение
нигде не обнаружено.
60. Too many procedure
(слишком много процедур)
Turbo Pascal
не допускает более 512 процедур или функций в модуле.
Если компилируется программа, то
нужно переместить несколько процедур или функций в модуль.
Если компилируется модуль, то его нужно разбить на два или более модулей.
61. Invalid typecast
(неправильное приведение типов)
— Размеры ссылки
на переменную и тип назначения отличаются при приведении типа переменной.
— Попытка приведения
типов в выражении, где допустима только ссылка на переменную.
62. Division by
zero (деление на ноль)
Попытка деления
на ноль.
63. Invalid file
type (неправильный тип файла)
Этот тип файла не поддерживается процедурой обработки файлов, например, readln
c типированным файлом или Seek c текстовым файлом.
64. Cannot Read or Write
variables of type (нельзя читать или писать переменные этого типа)
— Read
или Readln могут вводить значения
типа Char, Integer, Real, и String.
— Write или
Writeln могут выводить
значения типа Char, Integer, Real, String и Boolean.
65. Pointer
variable expected (ожидается переменная типа указатель)
Предыдущая переменная
должна иметь тип указатель.
66. String variable
expected (ожидается строковая переменая)
Предыдущая переменная
должна быть строкового типа.
67. String expession expected (ожидается выражение строкового типа)
Предыдущее выражение
должно быть строкового типа.
68. Circular unit
reference (циклическая ссылка на модуль)
Не допускается,
чтобы два модуля использовали друг друга:
unit U1; unit U2;
uses U2; uses U1;
… …
В этом примере
при выполнении MAKE для любого модуля будет
генерироваться ошибка 68.
69. Unit name mismatch
(несоответствие имени модуля)
Имя модуля, найденного
в .TPU файле , не соответствует имени, заданному в предложении USES.
70. Unit version mismatch
(несоответствие версии модуля)
Один или более
модулей, используемых данным модулем были изменены
после компиляции этого модуля. Для
автоматической компиляции модулей, которым
нужна перекомпиляция, нужно использовать
Compile/Make или Compile /Build в интегрированной
среде или опции / М или /В в компиляторе командной строки.
71. Duplicate
unit name (дублированное имя модуля)
В предложении
USES уже указано это имя модуля.
72. Unit file
format error (ошибка в формате файла модуля )
.TPU файл
почему-то неправильный; убедитесь,что этот файл
фактически является .TPU файлом.
73. Implementation
expected (ожидается ключевое слово
implementation)
74. Constant and
case types do not match (константа и тип
переключателя в операторе case не соответствуют друг другу)
Тип константы
оператора case несовместим с выражением переключателя в предложении case.
75. Record
variable expected (ожидается переменная типа record)
Предыдущая переменная
должна иметь тип record.
76. Constant
out of range (константа выходит за допустимый диапазон)
— Попытка индексировать
массив с помощью константы, выходящей за допустимый диапазон.
— Попытка присвоить
переменной константу, выходящую за допустимый диапазон.
— Попытка передать
константу, выходящую за допустимый
диапазон, в качестве параметра процедуры или функции.
77. File variable
expected (ожидается переменная типа file)
Предыдущая переменная
должна иметь тип file.
78. Pointer
expression expected (ожидается выражение типа
pointer).
79. Integer or
real expression expected (ожидается выражение типа integer
или real).
80. Label
not within current block (метка находится вне текущего блока).
Оператор goto
не может ссылаться на метку, находящуюся вне
текущего блока.
81. Label already
defined (метка уже определена)
Эта метка уже
помечает некоторый оператор.
82. Undefined
label in preceding
statement part (неопределенная метка в предыдущей
операторной части)
Эта метка была
объявлена и на нее есть ссылка в предыдущей
операторной части, но эта метка нигде не определена.
83. Invalid @ argument
(неправильный аргумент для @ )
Правильными аргументами
являются ссылки на переменные и идентификаторы
процедур или функций.
84. UNIT expected (ожидается
ключевое слово UNIT)
85. «;» expected
(ожидается ; )
86. «:» expected
(ожидается : )
87. «,» expected
(ожидается , )
88. «(» expected
(ожидается ( )
89. «)» expected
(ожидается ) )
90. «=» expected
(ожидается = )
91. «:=» expected
(ожидается := )
92. «[» or
«(.» expected (ожидается [ или (. )
93. «]» or
«.)» expected (ожидается ] или .) )
94. «.» expected
(ожидается . )
95. «..» expected
(ожидается .. )
96. Too many variables
(слишком много переменных)
— Общий размер
глобальных переменных, объявленных внутри программы
или модуля, не может превышать 64К.
— Общий размер
локальных переменных, объявленных внутри
процедуры или функции, не может превышать 64К.
97. Invalid FOR
control variable (неправильная управляющая переменная в
операторе for)
Управляющая переменная
в операторе for должна быть простой переменной,
определенной в описании текущей подпрограммы.
98. Integer variable
expected (ожидается переменная целого типа)
Предыдущая переменная
должна быть целого типа.
99. File and procedure
types are not allowed here (файловый и процедурный тип недопустимы
здесь)
Типированная константа
не может быть типа файлового или процедурного
типа.
100. String length mismatch
(длина строки не соответствует)
Длина строковой
константы не соответствует количеству компонент в символьном массиве.
101. Invalid
ordering of fields (неправильное упорядочивание полей)
Поля констант
типа record должны быть записаны в порядке объявления.
102. String
constant expected (ожидается константа типа string)
103. Integer or
real variable expected (ожидается переменная типа Integer
или Real)
Предыдущая переменная
должна быть типа Integer или Real.
104. Ordinal
variable expected (ожидается переменная порядкового типа )
Предыдущая переменная
должна быть порядкового типа .
105. INLINE error
(ошибка в INLINE)
Оператор < не допустим в сочетании с перемещаемыми ссылками на переменные, такие
ссылки всегда имеют размер, равный слову.
106. Character
expession expected (ожидается выражение
символьного типа)
Предыдущее выражение
должно быть типа Сhar.
107. Too many
relocation items (слишком много перемещаемых
элементов)
Размер перемещаемой
части таблицы в .EXE файле превышает 64К, что является верхним пределом
в Turbo Pascal. Если эта ошибка возникает,
то это означает, что данная программа слишком большая
для обработки редактором связей Turbo Pascal. Вероятно,
она будет слишком большой для выполнения в
DOS . В этом случае нужно разделить программу
на «главную» часть, которая выполняет две или
более «подпрограмм», используя процедуру EXEC в модуле Dos.
112. Case constant
out of range (константа оператора case выходит за
допустимый диапазон)
Для операторов
case целого типа константы должны быть внутри диапазона
-32768…32767.
113. Error in statement
(ошибка в операторе)
С этого символа не может
начинаться оператор.
114. Cannot call
an interrupt procedure (нельзя вызывать процедуру
прерывания)
116. Must be in
8087 mode to compile this (для компиляции этой конструкции должен быть
режим 8087)
Эта конструкция
может компилироваться только в состоянии {$N+}.
Операция над 8087 типами Single, Double, Extended
и Comp недопустимы в состоянии {$N-}.
117. Target address
not found (искомый адрес не найден)
Команда Compile/Search
Find Error в интегрированной среде или опция /F в версии командной строки
не может определить оператор, который соответствует
данному адресу.
118. Include files
are not allowed here (здесь недопустимы включаемые
файлы)
Каждая операторная
часть должна полностью содержаться в данном файле.
120. NIL expected (ожидается
NIL)
121. Invalid Qualifier
(неправильный квалификатор)
— Попытка индексировать
переменную, которая отсутствует в массиве.
— Попытка задать
поля в переменной, которая не является
записью.
— Попытка
получить значение, на
которое указывает переменная, не являющаяся указателем.
122. Invalid
variable reference (неправильная ссылка на переменную)
Предыдущая конструкция
следует синтаксису ссылки
на переменную, но не обозначает размещение памяти. Наиболее вероятно,
Вы вызвали функцию указателя, но забыли получить
значение, на которое указывает результат.
123. Too many
symbols (слишком много символов)
Программа или
модуль объявляет более 64К символов. Если
программа или модуль компилируется с опцией {$D+}, то попробуйте ее
выключить — заметим, однако, что
это будет препятствовать нахождению ошибок выполнения
в этом модуле. В противном
случае, можно попробовать переместить
несколько объявлений в отдельный модуль.
124. Statement
part too large (операторная часть слишком
большая)
Turbo Pascal
ограничивает размер операторной части около 24К. Если встречается эта
ошибка, то переместите разделы операторной части
в одну или более процедур. В любом случае, если
программа имеет операторную часть такого размера, то имеет
смысл прояснить структуру этой программы.
126. Files
must be var parameters (файлы
должны быть переменными параметрами)
Попытка объявить
значение параметра файлового типа. Параметры файлового типа должны
быть переменными параметрами.
127. Too many conditional
symbols (слишком много условных символов)
Для определения
дополнительных условных символов недостаточно места. Попытайтесь
исключить несколько символов или укоротить несколько
символических имен.
128. Misplaced
conditional directive (неправильно расположенная условная директива)
Компилятор встретил
директиву {$ELSE} или {$ENDIF} без
соответствующей директивы {$IFDEF}, {$IFNDEF} или {$IFOPT}.
129. ENDIF directive
missing (отсутствует директива ENDIF)
Исходный файл заканчивается
внутри конструкции условной компиляции.
В исходном файле должно быть одинаковое количество
директив {$IFxxx} и {$ENDIF}.
130. Error in initial
conditional defines (ошибка в начальных условных определениях)
Начальные условные
символы, заданные в Options/ Compiler/ Conditional
defines или в директиве /D, неправильные. Turbo Pascal ожидает,
что 0 или более иденитификаторов разделяются пробелами,
запятыми или точками с запятой.
131. Header does
not match previous definition (заголовок не соответствует
предыдущему определению)
— Заголовок
процедуры или функции, заданный в интерфейсной части
или в объявлении forward, не соответствует данному заголовку.
132. Critical
dick error (критическая ошибка диска)
Критическая ошибка
произошла во время компиляции (например, ошибка неготовности носителя)
133. Cannot
evaluate this expression (нельзя вычислить это выражение)
Попытка использовать
неподдерживаемое Turbo Pascal свойство в константном выражении
или в отладочном выражении. Например, Вы пытаетесь
использовать функцию Sin в объявлении константы, или Вы
пытаетесь вызвать функцию, определенную пользователем, в отладочном
выражении. Описание допустимого синтаксиса конкретных
выражений приведено в главе 1 «Лексемы и константы».
Описание допустимого синтаксиса отладочных выражений приведено
в главе 5 Руководства пользователя «Отладка программ
на Turbo Pascal».
134. Expession
incorrectly terminated (выражение завершается неправильно)
Turbo Pascal ожидает
или оператор, или конец выражения в этой точке, но ничего не находит.
135. Invalid
format specifier (неправильный спецификатор
формата )
Используется неправильный
спецификатор формата или числовой аргумент спецификатора
формата выходит за допустимый диапазон. Список
правильных спецификаторов формата приведен в
главе 5 Руководства пользователя «Отладка программ
на Turbo Pascal».
136. Invalid
indirect reference (неправильная косвенная
ссылка)
Оператор пытается
сделать неправильную косвенную ссылку.
Например, используется absolute переменная,
у которой базовая переменная неизвестна в текущем
модуле или используется inline программа, которая
ссылается на переменную, неизвестную в текущем модуле.
137. Structured variables
are not allowed here (структурные переменные недопустимы
здесь)
Попытка выполнить не поддерживаемую Turbo Pascal операцию над структурной переменной.
Например, попытка умножить две записи.
138. Cannot evaluate
without System unit (Нельзя вычислить без модуля System)
Библиотека TURBO.TPL
должна содержать модуль System для того,
чтобы отладчик мог вычислить выражение.
139. Cannot access
this symbol (невозможен доступ к этому
символу)
Все множество
символов в программе доступно сразу после
компиляции программы. Однако, к некоторым символам,
таким как переменные, невозможен доступ до
тех пор, пока программа не начинает фактически
выполняться.
140.Invalid floating-point
operation (Неправильная операция с плавающей точкой)
Операция над
двумя значениями вещественного типа привела к переполнению
или является делением на ноль.
141. Cannot compile
overlay to memory (нельзя компилировать оверлей в память)
Программа, которая
использует оверлеи, должна компилироваться на диск.
142. Procedure
or function variable expected (ожидается
переменная типа procedure или function)
В этом контексте
оператор адреса (@) может использоваться только с
переменной процедуры или функции.
143. Invalid procedure
or function reference (неправильная ссылка на процедуру
или функцию)
— Если процедура
или функция должны быть присвоены переменной типа procedure, то
их нужно компилировать в состоянии {$F+} и их нельзя объявлять
с ключевыми словами inline или interrupt.
— Вы пытаетесь вызвать
процедуру в выражении.
144. Cannot overlay
this unit (нельзя сделать этот модуль
оверлейным)
Попытка сделать
оверлейным модуль, который
не был откомпилирован в состоянии {$O+}.
147 Object type expected
(Ожидается объектный тип.)
Идентификатор не является объектным типом.
148 Local object
types are not allowed. (Локальный объектный тип недопустим.)
Объектный тип
может быть определен только в самой внешней
сфере действия программы или модуля. Определение объектного типа внутри процедур или функций недопустимо.
149 VIRTUAL expected.
(VIRTUAL ожидается.)
Пропущено ключевое
слово VIRTUAL.
150 Method
identifier expected. (Идентификатор метода ожидается.)
Идентификатор
не является методом.
151 Virtual
constructors are not allowed. (Виртуальные констракторы неразрешены.)
Констрактор-метод
должен быть статическим.
152 Constructor
identifier expected. (Идентификатор
констрактора ожидается.)
Идентификатор
не является констрактором.
153 Destructor
identifier expected. (Идентификатор дестрактора ожидается.)
Идентификатор
не является дестрактором.
154 Fail
only allowed withing constructors. (Fail допустим
только внутри констракторов.)
Стандартная процедура
Fail может быть использована только внутри констракторов.
155. Invalid
combination of opcode and operands (Неверная
комбинация кода операции и операндов)
Код операции
не допускает такой комбинации операндов. Возможные причины:
— Слишком много
или слишком мало операндов для этого кода операции;
например
INC AX, BX или MOV AX
— Правильное число
операндов, но их тип или порядок не соответствуют коду операции; например
DEC 1, MOV AX,CL или MOV 1,AX
156. Memory reference
expected (Ожидается ссылка на память)
Этот операнд не
ссылка на память, которая ожидается здесь. Вероятно, Вы
забыли поставить [] вокруг регистрового операнда. Например
MOV AX, BX+SI
вместо MOV AX, [BX+SI]
157. Cannot
add or subtract relocatable symbols (Нельзя
складывать или вычитать переместимые символы)
Над переместимыми
символами можно выполнять только сложение и вычитание констант.
Переменные, процедуры, функции и метки — это переместимые
символы. Считая, что Var — это переменная, а Const — это
константа, инструкции MOV AX, Const+Const и MOV AX, Var+Const — верны,
а MOV AX, Var+Var — нет.
158. Invalid
register combination (Неверная комбинация
регистров)
Правильные индексные
регистровые комбинации: [BX], [BP], [SI], [DI], [BX+SI], [BX+DI],
[BP+SI], [BP+DI]. Другие индексные
регистровые комбинации (такие, как [AX], [BP+BX], [SI+DX]) — не разрешены.
Примечание: Локальные
переменные (переменные, объявленные в процедурах и
функциях) всегда распределяются в стеке и доступ к ним производится
через регистр BP. Ассемблер автоматически добавляет
[BP] в ссылках на такие переменные. Так, что даже хотя конструкция
такая, как Local[BX] (где Local — локальная переменная) появляется
правильной, это не так, поскольку результирующий
операнд будет: Local[BP+BX].
159. 286/287 Instructions
are not enabled (Инструкции 286/287 не разрешены.)
Используйте директиву
компилятора {$G+}, чтобы разрешить коды операций 286/287,
но помните, что результирующий код не может выполняться на компьютерах с 8086 или 8088.
160. Invalid symbol reference
(Неверная ссылка на символ)
К этому
символу нельзя обращаться в ассемблерном операнде.
Возможные причины:
— Вы пытаетесь
обратиться в ассемблерном операнде к стандартной процедуре, стандартной функции или специальным массивам
Mem, MemW, MemL, Pоrt, PortW.
— Вы пытаетесь обратиться
в ассемблерном операнде к константе типа строка, плававающая точка
или множество.
— Вы пытаетесь обратиться
к специальному символу @Result вне функции.
— Вы пытаетесь обратиться
в ассемблерном операнде к inline процедуре или
функции.
— Вы пытаетесь сгенерировать
короткую JMP инструкцию, которая переходит на что-либо отличное
от метки.
161. Code generation
error (Ошибка генерации кода)
Предыдущая операторная
часть содержит инструкцию: LOOPNE, LOOPE, LOOP или
JCXZ, которая не может достичь метки назначения.
162. ASM expected (Ожидается
ASM)
[начало] [оглавление]
Ошибки времени выполнения.
Некоторые ошибки
во время выполнения программы приводят
к тому, что программа выводит на дисплей
сообщение об ошибке и завершается:
Run-time error
nnn at xxxх:yyyy (ошибка выполнения nnn по адресу
xxxх:yyyy, где nnn-номер
ошибки выполнения, а xxxx:yyyy —
адрес ошибки выполнения (сегмент и смещение))
Ошибки выполнения разделены
на четыре категории:
ошибки операционной системы DOS:1-99
ошибки ввода/вывода:100-149
критические ошибки :150-199
фатальные ошибки:200-255.
[начало] [оглавление]
Ошибки операционной системы DOS.
1. Invalid function
number (Неверный номер функции)
Вы вызываете несуществующую
функцию DOS.
2. File not found
(файл не найден)
Сообщается процедурами
Reset, Append, Rename или Erase, если имя назначенное файловой
переменной не задает существующий файл.
3. Path not fond
(путь не найден)
— Сообщается процедурами
Reset, Rewrite, Append, Rename или Erase, если
имя, назначенное файловой переменной, неправильное или задает
несуществующий подсправочник.
— Сообщается
процедурами Chdir, Mkdir или Rmdir, если путь доступа
неправильный или задает несуществующий подсправочник.
4. Too many open
files (слишком много открытых файлов)
Сообщается процедурами
Reset, Rewrite или Append,
если программа имеет слишком много открытых
файлов. DOS никогда не разрешает более 15 открытых файлов на процесс.
Если встречается эта ошибка, когда открытых файлов меньше 15,
то это может указывать на то, что файл CONFIG.SYS не содержит
запись FILES =XX или, что эта запись задает слишком
мало файлов. Увеличьте это количество до некоторого
подходящего значения, например, до 20.
5. File access denied
(запрещен доступ к файлу)
— Сообщается
процедурами Reset или Append, если FileMode
разрешает запись, а имя, назначенное файловой переменной, задает справочник или файл, предназначенный только для считывания.
— Сообщается процедурой
Rewrite, если справочник заполнен или если имя, присвоенное
файловой переменной, задает справочник или существующий
файл, предназначенный только для считывания.
— Сообщается процедурой
Rename, если имя, присвоенное файловой переменной, задает
справочник или если новое
имя задает существующий файл.
— Сообщается процедурой
Erase, если имя, присвоенное файловой переменной, задает
справочник или файл, предназначенный только для считывания.
— Сообщается процедурой
MkDir, если файл с таким именем существует
в «родительском «справочнике, или
если путь доступа задает устройство, или если нет места в «родительском» справочнике.
— Сообщается процедурой
RmDir, если справочник непустой; если путь доступа не задает справочник,
или если путь доступа задает корневой справочник.
— Сообщается процедурой
Read или BlockRead для типированного или нетипированного
файла, если этот файл не открыт для чтения.
— Сообщается процедурой
Write или BlockWrite для типированного или нетипированного файла, если
этот файл не открыт для записи.
6. Invalid file
handle (неправильный обработчик файла)
Эта ошибка сообщается,
если неправильный обработчик файла передается
вызову системы DOS. Это
никогда не должно происходить; если
это случается, то это указывает,что файловая
переменная каким-то образом запорчена.
12. Invalid file
access code (неправильный код доступа к файлу)
Сообщается процедурами Reset или Append для типированного или нетипированного файла,если значение
FileMode неправильное.
15. Invalid drive number
(неправильный номер устройства)
Сообщается процедурой
GetDir или ChangeDir, если номер устройства неправильный.
16. Cannot
remove current directory (нельзя удалять текущий справочник)
17. Cannot rename
across drives (нельзя переименовывать файлы, находящиеся на различных
устройствах)
Сообщается процедурой
Rename, если оба имени находятся на различных
устройствах.
[начало] [оглавление]
Ошибки ввода/вывода.
Эти ошибки
вызывают завершение программы, если этот оператор был откомпилирован
в состоянии {$I+}. В состоянии {$I-} программа продолжает
выполняться, а ошибка сообщается функцией IOResult.
100. Disk read error
(ошибка чтения с диска)
Сообщается процедурой
Read для типированного файла, если делается
попытка чтения после конца файла.
101. Disk write
error (ошибка записи на диск)
Сообщается процедурами
Close, Write, Writeln, Flush или Page, если диск становится полным.
102. File not
assigned (файл не назначен)
Сообщается процедурами
Reset, Rewrite, Append, Rename или Erase,
если файловой переменной не было присвоено имя с помощью
вызова Assign.
103. File not
open (файл не открыт)
Сообщается процедурами
Close, Read, Write, Eof, FileSize, Flush, BlockRead
или BlockWrite, если файл не открыт.
104. File not
open for input (файл не открыт для ввода)
Сообщается процедурами
Read, Readln, Eof, Eoln, SeekEof, SeekEoln
для текстовых файлов, если файл не открыт для ввода.
105. File not
open for output (файл не открыт для вывода)
Сообщается процедурами
Write и Writeln для текстовых файлов, если файл не открыт для
вывода.
106. Invalid numeric
format (неправильный числовой формат)
Сообщается процедурами
Read и Readln, если числовое значение, прочитанное
из текстового файла не соответствует правильному
числовому формату.
[начало] [оглавление]
Критические ошибки.
150. Disk is write-protected
(защита диска от записи)
151. Unknown unit
(неизвестное устройство)
152. Drive not
ready (устройство не готово)
153. Unknown command
(неизвестная команда)
154. CRC
error in data (ошибка циклического контроля по избыточности в данных)
155. Bad drive
reguest structure length (неправильный запрос устройства
о длине структуры)
156. Disk seek
error (ошибка поиска на диске)
157. Unknown media
type (неизвестный тип носителя)
158. Sector not
found (сектор не найден)
159. Printer out
of paper (на принтере нет бумаги)
160. Device write
fault (ошибка записи на устройство)
161. Device read
fault (ошибка чтения с устройства)
162. Hardware
failure (отказ аппаратного обеспечения)
Более подробная
информация о критических ошибках приведена в Руководстве программиста
для DOS.
[начало] [оглавление]
Фатальные ошибки.
Эти ошибки всегда
сразу же завершают программу.
200. Division
by zero (деление на ноль)
201. Ошибка
выхода за допустимый диапазон. Эта ошибка сообщается операторами, откомпилированными в состоянии {$R+},
когда возникает одна из следующих ситуаций:
— Индексное
выражение квалификатора массива выходит за допустимый диапазон.
— Была сделана
попытка присвоить переменной значение,
выходящее за допустимый диапазон.
— Была сделана
попытка передать процедуре или функции в качестве параметра значение, выходящее за допустимый диапазон.
202. Stack overflow
error (ошибка переполнения стека)
Эта ошибка сообщается
при входе в процедуру или функцию, откомпилированную
в состоянии {$S+}, когда в стеке нет достаточно места для
размещения локальных переменных подпрограмм. Увеличьте
размер стека с помощью директивы компилятора $M.
Эта ошибка может
возникать так же из-за бесконечной рекурсии.
203. Heap overflow
error (ошибка переполнения кучи)
Эта ошибка
сообщается процедурами New или GetMem , когда в куче
нет достаточно места для размещения блока требуемого размера.
Более подробное описание монитора кучи
приведено в главе 16 «Память».
204. Invalid
pointer operation (неправильная операция с указателем)
Эта ошибка
сообщается процедурами Dispose или FreeMem, если указатель
равен nil или указывает на позицию за пределами кучи или, если свободный
список не может быть расширен из-за того, что список свободных блоков
полон, или HeapPtr находится слишком близко от нижней границы списка свободных блоков.
205. Floating
point overflow (переполнение с плавающей точкой)
Операция с
плавающей точкой обрабатывает слишком большое для Turbo Pascal
или сопроцессора число.
206. Floating
point underflow (потеря значности при операции с плавающей точкой)
Операция с
плавающей точкой приводит к потере значности. Эта ошибка сообщается,
если только используется числовой сопроцессор 8087
с контрольным словом, которое не маскирует потерю значности
По умолчанию, потеря значности вызывает
возвращение нулевого результата.
207. Invalid floating
point operation (неправильная операция с плавающей точкой)
— Вещественное
значение, передаваемое Trunc или Round,
не может быть преобразовано в целое внутри диапазона для типа
LongInt (-2147483648 до 214783647)
— Аргумент, передаваемый
функции Sgrt, является отрицательным числом.
— Аргумент,
передаваемый функции Ln, равен
нулю или отрицательный.
— Произошло
переполнение стека сопроцессора 8087.
Более подробное описание корректного программирования при
использовании сопроцессора 8087 приведено в главе 14 «Использование
8087»
208. Overley
manager not installed (монитор оверлеев не инсталирован)
Программа вызывает
оверлейную процедуру или функцию, но
монитор оверлеев не инсталирован.
Наиболее вероятно, что
Вы не вызвали OvrInit или вызов OvrInit был неудачным. Заметим,
что если код инициализации находится в любом из
оверлейных модулей, то нужно создать дополнителный
неоверлейный модуль, который вызывает OvrInit и использовать
этот модуль перед любым из оверлейных модулей. Полное описание
монитора оверлеев приведено в главе 13 «Модуль Overlay» .
209. Overlay file
read error (ошибка чтения оверлейного файла)
Произошла ошибка
чтения, когда монитор оверлеев пытался
прочитать оверлей из оверлейного файла.
210. Object not
initialized. (Объект не инициализирован)
Когда включена
проверка диапазона, Вы вызываете виртуальный метод
объекта до инициализации объекта через вызов констрактора.
211. Call to abstract
method. (Вызов абстрактного метода)
Эта ошибка
генерируется процедурой Abstract в модуле Objects; она указывает,
что Ваша программа пытается выполнить абстрактный витруальный
метод. Когда объектный тип содержить один или
более абстрактных методов, он называется абстрактным
объектным типом. Будет ошибкой создавать экземпляры
объектов абстрактного типа — абстрактные типы существуют
только для того, чтобы Вы могли
наследовать от них и перекрывать абстрактные методы.
Например, метод
Compare типа TSortedCollection в модуле
Objects абстрактный, указывает на то,
что для реализации отсортированного набора
Вы должны создать объектный тип, который наследуется от
TSortedCollection и перекрывает метод Compare.
212. Stream registration
error. (Ошибка регистрации потока)
Эта ошибка
генерируется процедурой RegisterType в модуле Objects, указывая, что возникла одна из ошибок:
— Запись регистрации
потока не размещается в сегменте данных.
— Поле ObjType
записи регистрации потока = 0.
— Тип уже зарегистрирован.
— Существует другой
тип с тем же значением ObjType.
213. Collection
index out of range. (Индекс набора выходит за пределы)
Индекс, переданный
в метод из TCollection, выходит за пределы.
214. Collection
overflow error. (Ошибка переполнения набора)
Эта ошибка выдается
TCollection при попытке добавить элемент, когда набор не может
быть расширен.
[начало]
[оглавление]
Предыдущая
страница | Следующая
страница