Что значит повторно объявленный идентификатор в паскале
Что значит повторно объявленный идентификатор в паскале
Вот что получается, если попытаться скомпилировать командой Ctrl+K простой модуль с синтаксическими ошибками ( правое окошко ) :
В рабочем журнале слева есть две записи о двух попытках компиляции с указанием количества ошибок, найденных компилятором каждый раз. Только вторая запись имеет отношение к текущему состоянию окошка с текстом модуля справа: каждой из 5 ошибок соответствует черный квадратик.
По завершении компиляции курсор стоит сразу после первой ошибки (вертикальная линия). В самом низу в статусной полоске слева видно сообщение компилятора о данной ошибке: «повторно объявленный идентификатор». Действительно, идентификатор x уже был описан в качестве формального параметра процедуры.
Устраняйте самую первую ошибку — и сразу компилируйте снова, нажимая Ctrl+K (см. заповеди.)
Не следует пытаться сразу устранить все ошибки: компилятор после первой ошибки может «сбиться» и неправильно интерпретировать дальнейший текст — например, увидеть ошибки там, где их на самом деле нет, или пропустить настоящие ошибки. Разумеется, некоторые очевидные ошибки можно устранить одновременно.
Скорость компиляции достаточно велика, чтобы при такой методе неудобств не возникало.
Чтобы все-таки посмотреть, что за ошибки нашел компилятор в остальных случаях, достаточно кликнуть (один раз) мышкой по любому черному квадрату: в левой части статусной полоски возникнет соответствующее сообщение. Вот пять этих сообщений для пяти ошибок, показанных на картинке ( в квадратных скобках — пояснения ) :
После устранение первых трех ошибок (каждый раз производилась компиляция, что видно из записей в рабочем журнале), получится следующее:
Видно, что после вставки точки запятой (ошибка 3 в первоначальном списке), компилятор точнее интерпретирует данную ошибку (зато он перестал видеть пятую ошибку из списка). Исправляя Stdlog на StdLog и компилируя, получаем:
Компилятор снова увидел ошибку 5 из списка. Остается ее исправить (достаточно скопировать в это место имя процедуры) и нажать Ctrl+K :
В рабочем журнале теперь нет сообщения о найденных ошибках — зато указан размер получившегося машинного кода (64 байта; второе число — 0 — относится к глобальным переменным модуля, объявляемым до всех процедур модуля; таких переменных в данном примере нет).
Повторно объявленный идентификатор паскаль
Повторно объявленный идентификатор паскаль
Наука — Школе
Как компилятор сообщает об ошибках
Вот что получается, если попытаться скомпилировать командой Ctrl+K простой модуль с синтаксическими ошибками ( правое окошко ) :
‘ width=’8′ height=’8’ /> Прочтите прежде чем задавать вопрос!
Группа: Пользователи
Сообщений: 1
Пол: Мужской
Репутация:
Сообщение отредактировано: RabbitRabbit — 10.10.2016 17:41
Большевик–концептуал
Группа: Пользователи
Сообщений: 188
Пол: Мужской
Реальное имя: Иван Левашев
Jabber: bu_gen@octagram.name
Skype: i.levashew
QQ: 3152538431
WeChat
Ада: Сторонник
Embarcadero Delphi: Сторонник
Free Pascal: Разработчик
Turbo Pascal: Установлен
Репутация: 1
Выглядит так, будто был код для Turbo Pascal с функцией Power, а потом функцию Power в сигнатуре переименовали в F, забыв поменять имя при возврате результата. В Turbo Pascal не было псевдопеременной Result, вместо этого, чтобы вернуть результат, нужно было присвоит значение псевдопеременной, имя которой совпадает с именем функции, однако в неё можно только писать, а если пытаться читать, компилятор воспринимает это как рекурсивный вызов, и если нужно читать, то создавалась ещё одна переменная, в данном случае Result, а при выходе из функции «Power := Result;» должен был передать значение этой переменной в окончательный результат.
Если совместимость с Turbo Pascal не требуется, нужно убрать строки с объявлением переменной Result и присваиванием «Power := Result;». Если требуется, то заменить Result везде на какое–то другое имя, например, ProtoResult, а в последнем присваивании тогда будет «F := ProtoResult;»
Сообщения об ошибках компиляции
1. Out of memory (не хватает памяти). Эта ошибка происходит, когда компилятору не хватает памяти. В этом случае нужно разбить модуль на два или большее количество меньших модулей.
2. Identifier expected (ожидается идентификатор). В этой точке предполагался идентификатор. Возможно, Вы пытаетесь повторно объявить зарезервированное слово.
3. Unknown identifier (неизвестный идентификатор). Этот идентификатор не объявлен в данном модуле.
4. Duplicate identifier (дублируемый идентификатор). Этот идентификатор уже был использован в текущем блоке.
5. Syntax error (синтаксическая ошибка). Ошибка с точки зрения грамматики языка.
6. Error in real constant (ошибка в записи константы вещественного типа).
7. Error in integer constant (ошибка в записи константы целого типа).
8. String constant exceeds line (строковая константа выходит за пределы строки – слишком длинная). Наиболее вероятно, что Вы забыли закрывающую кавычку в строковой константе.
11. Line too long (строка слишком длинная). Максимальная длина строки равна 126 символам.
12. Type identifier expected (ожидается тип идентификатора). Этот идентификатор не обозначает тип, как это должно быть.
14. Invalid file name (неправильное имя файла). Неправильное имя файла или задается несуществующий путь доступа.
15. File not found (файл не найден).
16. Disk full (диск полон). Удалите несколько файлов или используйте новый диск.
18. Too many files (слишком много файлов).
20. Variable identifier expected (ожидается идентификатор переменной). Этот идентификатор не обозначает переменную, как это должно быть.
21. Error in type (ошибка в типе). Этот символ не может начинать определение типа.
25. Invalid string length (неправильная длина строки). Объявленная максимальная длина строки должна быть в диапазоне 1.255.
26. Type mismatch (несоответствие типов). Это может быть по следующим причинам:
· несовместимые типы переменной и выражения в операторе присваивания;
· несовместимые типы фактического и формального параметра в вызове процедуры или функции;
· тип выражения, который несовместим с типом индекса в индексации массива;
· несовместимые типы операндов в выражении.
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 (ожидается выражение булевского типа).
42. Error in expression (ошибка в выражении). Возможно, Вы забыли написать оператор между двумя операндами.
43. Illegal assignment( неправильное присваивание ). Идентификатору функции можно присваивать значения только внутри операторной части функции.
48. Code Segment too large (сегмент кода слишком большой). Максимальный размер кода программы или модуля равен 65520 байт. Если компилируется программа, то нужно перенести несколько процедур или функций в модуль. Если компилируется модуль, то его нужно разбить на два или больше модулей.
49. Data segment too large (сегмент данных слишком большой). Максимальный размер сегмента данных программы равен 65520 байт, включая данные, объявленные используемыми модулями.
50. Do expеcted (ожидается ключевое слово Do).
54. Of expected (ожидается ключевое слово Of).
57. Then expected (ожидается ключевое слово then).
58. Tо or Downto expected (ожидается ключевое слово to или downto).
60. Too many procedure (слишком много процедур). Турбо-Паскаль не допускает более 512 процедур или функций в модуле.
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.
66. String variable expected (ожидается строковая переменая).
67. String expession expected (ожидается выражение строкового типа).
71. Duplicate unit name (дублированное имя модуля).
74. Constant and case types do not match (константа и тип переключателя в операторе case не соответствуют друг другу).
76. Constant out of range (константа выходит за допустимый диапазон):
· попытка индексировать массив с помощью константы, выходящей за допустимый диапазон;
· попытка присвоить переменной константу, выходящую за допустимый диапазон;
· попытка передать константу, выходящую за допустимый диапазон, в качестве параметра процедуры или функции.
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 (неопределенная метка в предыдущей операторной части). Эта метка была объявлена, и на нее есть ссылка в предыдущей операторной части, но эта метка нигде не определена.
84. UNIT expected (ожидается ключевое слово UNIT).
85. «;» expected (ожидается ; ).
86. «:» expected ( ожидается : ).
88. «(» expected ( ожидается ( ).
89. «)» expected ( ожидается ) ).
90. «=» expected ( ожидается = ).
91. «:=» expected ( ожидается := ).
92. «[» or «(.» expected ( ожидается [ или (. ).
97. Invalid FOR control variable (неправильная управляющая переменная в операторе for).
98. Integer variable expected (ожидается переменная целого типа).
100. String length mismatch (длина строки не соответствует). Длина строковой константы не соответствует количеству компонентов в символьном массиве.
102. String constant expected (ожидается константа типа string).
103. Integer or real variable expected (ожидается переменная типа Integer или Real).
106. Character expession expected (ожидается выражение символьного типа).
113. Error in statement ( ошибка в операторе ). С этого символа не может начинаться оператор.
124. Statement part too large (операторная часть слишком большая).
Турбо-Паскаль ограничивает размер операторной части около 24К. Если встречается эта ошибка, то переместите разделы операторной части в одну или более процедур. В любом случае, если программа имеет операторную часть такого размера, то имеет смысл прояснить структуру этой программы.
132. Critical dick error (критическая ошибка диска). Критическая ошибка произошла во время компиляции (например, ошибка неготовности носителя)
Ошибки выполнения
Ошибки выполнения разделены на четыре категории:
Заметки о Pascal, Delphi и Lazarus
Следует ожидать переводов разделов справочной системы Delphi, компиляций из учебников, переводы статей, «путевые заметки» и прочие интересности. Блог прежде всего ориентирован на студентов, но опытных людей я тоже буду рад видеть;-)
воскресенье, 20 марта 2011 г.
Блоки и область видимости
Объявления и инструкции организованы в виде блоков, которые определяют локальные пространства имен (или области видимости) для меток и идентификаторов. Блоки позволяют одному и тому же идентификатору (например, имени переменной) иметь различный смысл в разных частях программы. Каждый блок – это часть объявления программы, функции или процедуры. Объявление каждой программы, процедуры или функции имеет один блок.
Блоки
Блок состоит из последовательности объявлений, за которым следует составная инструкция. Все объявления должны идти вместе, в начале блока. То есть блок имеет форму:
Секция declarations может включать в себя объявления переменных, констант (включая resource strings), типов, процедур, функций и меток. В блоке программы могут также присутствовать один или несколько разделов exports (см. Libraries and Packages.)
Например, при объявлении функции:
первая строка объявления – это заголовок функции и все последующие строки составляют блок. Ch, L, Source, и Dest – это локальные переменные, их объявления действительны только внутри блока функции UpperCase и в этом блоке они перекрывают любые объявления таких же идентификаторов, которые могут встретиться в блоке программы или секциях interface или implementation в модуле.
Область видимости
Идентификатор (например, переменная или имя функции) может быть использован только внутри области видимости своего объявления. Расположение объявления определяет его область видимости. Идентификатор, объявленный внутри объявления программы, функции или процедуры имеет область видимости, ограниченную блоком, в котором он объявлен. Идентификатор, объявленный в секции interface в модуле имеет область видимости, которая включает в себя все модули и программы, которые подключают этот модуль. Идентификаторы с меньшей областью видимости, особенно идентификаторы, объявленные в функциях и процедурах, иногда называются локальными, а идентификаторы с большей областью видимости называются глобальными.
Правила, которые определяют область видимости идентификатора, могут быть сведены в таблицу:
Конфликты имен
Когда один блок включает в себя другой, они называются соответственно внешним и внутренним блоками. Если идентификатор объявлен во внешнем блоке и повторно объявлен во внутреннем блоке, объявление во внутреннем блоке имеет преимущество перед объявлением во внешнем и определяет смысл идентификатора на протяжении всего внутреннего блока. Например, если вы объявляете переменную MaxValue в секции interface модуля, и затем объявляете еще одну переменную с таким же именем внутри функции, объявленной в этом модуле, все неспецифицированные обращения к MaxValue внутри блока функции обрабатываются как второе, локальное объявление. Аналогично, функция, объявленная внутри другой функции создает новое внутреннее пространство имен, в которм идентификаторы, объявленные во внешней функции могут быть объявлены заново как локальные.
Использование нескольких модулей может усложнить определение области видимости. Каждый модуль, перечисленный в разделе подключения, создает новую область видимости, которая охватывает все модули, подключенные позже и непосредственно программу или модуль, содержащий рассматриваемый раздел подключения модулей. Первый модуль в разделе подключения представляет собой самую внешнюю область видимости, и каждый последующий модули представляет собой новую область видимости внутри предыдущей. Если два или более модуля объявляют одинаковые идентификаторы в своих секциях interface, то при неспецифицированном обращении к идентификатору выбирается самая внутренняя область видимости. То есть, выбирается тот модуль в котором непосредственно происходит обращение, или, если в этом модуле нет объявления идентификатора, выбирается модуль, последний подходящий модуль в разделе подключения модулей.
Модули System и SysInit подключаются автоматически ко всем программам и модулям. Объявления в модуле System, включая все предопределенные типы, подпрограммы и константы, которые компилятор понимает автоматически, всегда имеют более внешнюю область видимости.
Вы можете перекрыть эти правила и обойти внутреннее объявление, используя идентификатор со спецификатором или воспользовавшись инструкцией with.
Локальные и глобальные идентификаторы Паскаль
Когда мы используем процедуры и функции в Паскале, то имеем дело с идентификаторами (т.е. именами) в программе. При составлении программного кода для использования не все имена оказываются доступными.
Доступ к определенному идентификатору в тот или иной момент времени осуществляется в зависимости от того, в каком блоке описан используемый идентификатор.
Помните: формальные параметры функций и процедур всегда представляют собой локальные переменные для тех блоков, где они описаны. Существует два типа идентификаторов: локальные и глобальные идентификаторы Паскаль.
Локальные идентификаторы Паскаль:
Локальные идентификаторы — это имена, которые описаны либо в заголовке, либо в разделе описаний функции или процедуры. Основное правило работы с такими идентификаторами: Локальные идентификаторы являются доступными только лишь в пределах того блока, в котором они описаны.
Этот блок, а также все остальные блоки, вложенные в него, называются областью видимости для соответствующих локальных идентификаторов.
Глобальные идентификаторы Паскаль:
Глобальные идентификаторы — это имена, заключенные в блоке Program, используемом для всей программы. При работе с этим типом идентификаторов следует руководствоваться правилом.
Идентификаторы, которые описаны в одном блоке, могут совпасть с идентификаторами из других блоков, которые либо содержат данный блок, либо вложены в него. Причиной этому является тот факт, что переменные, которые описаны в различных блоках (пусть у них всех одинаковые имена), хранятся в различных областях ОЗУ (оперативная память).
Область памяти, хранящая глобальные идентификаторы, называется сегментом данных программы. Их создание происходит в процессе компиляции, и кроме того они действительны на протяжении всей работы программы. Локальные переменные, в отличие от глобальных, хранятся в области памяти, которая именуется стеком. Они временны, поскольку их создание осуществляется в момент входа в подпрограмму, а уничтожение — в момент выхода из подпрограммы.
Может возникнуть ситуация, когда имя, которое описано в блоке, в случае совпадения «закрывает» те же самые имена из блоков, содержащих данный.
Другими словами, если есть два блока, один из которых вложен в другой, и в обоих блоках содержатся переменные с одинаковыми именами, то после перехода во «внутренний» блок мы будем работать с переменной, локальной для рассматриваемого блока. А переменная с этим же именем, заключенная во «внешнем» блоке, оказывается временно недоступна — это будет продолжаться до тех пор, пока не осуществим выход из «внутреннего» блока. Совет.
Все имена, имеющие в той или иной подпрограмме только лишь вспомогательное назначение, идентифицировать в качестве локальных, что избавляет от опасности изменений глобальных объектов с теми же именами.
Пример. Создадим программу, которая вычисляет значение функции y=a*ln(sin(x))
Pascal | Коды ошибок
СООБЩЕНИЯ КОМПИЛЯТОРА ОБ ОШИБКАХ
1 | Out of memory | Выход за границы памяти | Компилятор выполняется вне допустимых границ памяти. Имеется ряд возможных решений проблемы: |
§ Если в меню Options?Linker?Link Buffer, установлен параметр Memory, переключите его в значение Disk.
§ Возможно программа слишком велика, чтобы компилироваться в таком объеме памяти. Следует разбить ее на два или более модуля.
§ несоответствующее количество begin и end (не забудьте, что оператор case также заканчивается словом end);
§ включаемый файл заканчивается в середине раздела операторов. Каждый раздел операторов должен целиком помещаться в одном файле;
§ незаконченный комментарий.
§ несовместимые типы переменной и выражения в операторе присваивания;
§ несовместимые типы фактического и формального параметров в обращении к процедуре или функции;
§ тип выражения, несовместимый с типом индекса при индексировании массива;
§ несовместимые типы операндов в выражении.
§ Идентификатору функции можно присваивать значения только внутри раздела операторов данной функции.
§ Идентификатор обозначает абсолютную переменную.
§ Идентификатор обозначает процедуру или функцию типа inline.
§ Файл .com содержит ссылки с размерами в байтах на перемещаемые идентификаторы. Такая ошибка происходит в случае, если вы используете операторы HIGH и DOWN с перемещаемыми идентификаторами или если вы ссылаетесь в директивах DB на перемещаемые идентификаторы.
§ Операнд ссылается на перемещаемый идентификатор, который не был определен в сегменте CODE или в сегменте DATA.
§ Операнд ссылается на процедуру EXTRN или функцию EXTRN со смещением, например CALL SortProc+8.
§ Процедуры или функции были описаны с помощью описания forward, но их определение не найдено.
§ Вы пытаетесь осуществить приведение типа выражения, когда разрешается только ссылка на переменную, процедуру или функцию.
§ Вы пытаетесь присвоить константу вне диапазона переменной.