Режимы компиляции |
18.04.2005 Иван Шихалев |
Режимы компиляции, или иначе — режимы совместимости, в Free Pascal определяют, каким диалектом языка Pascal вы хотите воспользоваться. Режим определяет возможные конструкции языка, некоторые типы данных и системные модули подгружаемые по умолчанию.
Режим компиляции выставляется при помощи ключа командной строки -S или непосредственно в модуле при помощи директивы {$MODE xxx}.
В этом же обзоре я намерен описать прочие ключи компилятора, определяющие расширения языка.
{$MODE FPC}Режим по умолчанию. Соответственно в ключах командной строки своего символа не имеет. Что, впрочем, не есть хорошо, поскольку существует же еще и файл ppc386.cfg — его установки таким образом мы можем сменить на FPC только через директиву.
При присваивании значения процедурной переменной вы можете использовать как @<proc_name>, так и просто <proc_name>. Что самое интересное — это распространяется и на функции. Выражение @<proc_var> однозначно трактуется как адрес переменной, а не процедуры, на которую она ссылается. Кстати, в справке по этому поводу ошибка, или я что-то не так понял: "You must use the address operator to assign procedural variables."
Заголовок предварительно объявленной (в интерфейсной части модуля или при помощи директивы forward) функции или процедуры должен полностью совпадать с ее заголовком при реализации. То есть опускать список аргументов и тип результата — нельзя.
Разрешена перегрузка (overloading) процедур и функций. Кстати, в отличие от Delphi, директиву overload использовать необязательно.
Разрешены вложенные комментарии, таким образом, конструкция { comment { nested comment } } не вызовет ошибки компилятора.
Не поддерживаются классы. Из-за того, что обработка исключений реализована a-la Delphi, не поддерживается оператор try.
Не подгружается модуль ObjPas. Что это за зверь, я слегка опишу, когда перейдем к {$MODE OBJFPC}, пока лишь замечу, что тип integer без ObjPas соответствует 2м байтам, а с ним — 4м.
Не поддерживается ключевое слово resourcestring.
До кучи ко всем огорчениям, не поддерживается псевдо(?)переменная result — результат функции присваивается ее имени.
Зато поддерживается директива cvar и внешние переменные.
Автоматически производится присваивание PChar -> string.
Поддерживается такая замечательная вещь, как перегрузка операторов.
{$MODE TP}Режим совместимости с Turbo Pascal фирмы Borland версии 7. Соответствует ключу командной строки -So.
Совместимость обеспечивается полная — единственное различие в том, что исполняемый файл 32-разрядный, других Free Pascal не создает.
Писать программы непосредственно в этом режиме, на мой взгляд — мазохизм. А вот портировать старые программы для TP легко — как правило, не требуется вносить каких-либо изменений в код.
В силу полной совместимости, воздержусь от подробного описания этого режима — чего-чего, а уж литературы по Turbo Pascal достаточно, и в Сети, и в книжных магазинах.
{$MODE GPC}По идее — режим совместимости с GPC — GNU Pascal. Ключ командной строки — -Sp.
Судя по всему — разработка данного режима для команды FPC — мягко говоря, задача не приоритетная. Реально никаких свойственных GPC расширений не поддерживается, и от {$MODE TP} этот режим отличается только использованием адресного оператора для процедурных переменных.
{$MODE OBJFPC}Это — режим Object Pascal. Соответствует ключу командной строки -S2.
Работа с процедурными переменными полностью аналогична режиму {$MODE FPC}. Аналогично с заголовками функций и процедур — они должны повторяться в точности при реализации. Вообще, режимы очень похожи, главное отличие — поддержка классов.
Классы почти полностью идентичны классам в Delphi. Естественно, published практически эквивалентно public. Кроме того, перегрузка методов не требует директивы overload. Обидно, что не поддерживаются интерфейсы, но авторы обещают сделать это к версии 1.2.
Автоматически подгружается модуль ObjPas. Данный модуль по сути дополняет функциональность модуля System с уровня Turbo Pascal до уровня Delphi. Хотя, конечно, это грубое упрощение. Что реально он делает?
smallint — целое со знаком длиной в слово, и переопределяет тип integer — в отличие от других режимов он означает целое со знаком размером в двойное слово, что соответствует типу longint, который остается таким же.AssignFile и CloseFile.GetMem и FreeMem. К сожалению, я пока не ковырялся в исходниках и не могу сказать, что именно в их реализации изменено.Free Pascal при {$MODE OBJFPC} поддерживает работу с ресурсными строками, через resourcestring.
При написании функций, для возвращаемого значения можно использовать псевдопеременную result. Что на мой взгляд гораздо удобнее, чем имя функции, особенно при итерациях.
Преобразование PChar -> string производится при присваивании автоматически.
Второе (после классов) по важности преимущество данного режима — обработка исключений в блоках try ... except ... end и try ... finally ... end. Данный механизм Free Pascal поддерживает полностью аналогично Delphi — то есть вы можете перехватывать исключения, обрабатывать в зависимости от класса с помощью ключевого слова on, определять собственные классы исключений и вызывать их (или стандартные) посредством оператора raise. Для корректной работы с исключениями нужно подключать, как и в Delphi, модуль SysUtils, который содержит базовый класс Exception и стандартные классы исключений.
В общем и целом данный режим очень похож на Object Pascal a-la Borland Delphi. Разработчики намерены реализовать и интерфейсы к версии 1.2, но когда она выйдет, пока неизвестно.
{$MODE DELPHI}Режим совместимости с Borland Delphi версии 2, если я не ошибаюсь. Соответствует ключу командной строки -Sd.
От {$MODE OBJFPC} отличается весьма незначительно:
implementation повторять заголовок процедуры или функции.В целом, я бы рекомендовал все-таки {$MODE OBJFPC}, который соединяет в себе объектную модель Object Pascal со всеми прелестями собственно FPC.
Поддержка inline- процедур, функций и операторов. Определяется директивой компилятора {$INLINE ON/OFF} и ключом командной строки -Si. Inline-процедуры описываются директивой inline в заголовке, могут быть как нормальными паскалевскими, так и ассемблерными (при использовании директивы assembler), то есть не требуют знания машинных кодов, как директива inline в Turbo Pascal. При использовании этой возможности следует помнить, что в случае ошибки (рекурсия, etc.) компилятор почему-то не выдает осмысленного сообщения, а слетает на "Internal Error". Если inline-процедура используется за пределами программного модуля, где она непосредственно описана, то трактуется как обычная вызываемая процедура.
Поддержка простых макросов. Определяется директивой компилятора {$MACRO ON/OFF} и ключом командной строки -Sm. Сами макросы определяются так {$DEFINE MACRO_NAME := EXPRESSION}, где MACRO_NAME — идентификатор, который в дальнейшем тексте программы будет заменяться на выражение EXPRESSION.
Поддержка специальных операторов присваивания в стиле Си. Определяется ключом командной строки -Sc, собственной директивы компилятора не имеет. Разрешает присваивание с одновременным сложением, вычитанием, умножением или делением, используя операторы +=, -=, *= и /= соответственно.
| FPC | 3.2.2 | release |
| Lazarus | 3.2 | release |
| MSE | 5.10.0 | release |
| fpGUI | 1.4.1 | release |