Публикации FreePascal

Режимы компиляции

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, который остается таким же.
  • Во-вторых, для совместимости с Delphi определены процедуры 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, собственной ди­рек­ти­вы компилятора не имеет. Разрешает присваивание с одновременным сложением, вычитанием, умножением или делением, ис­поль­зуя операторы +=, -=, *= и /= соответственно.

Актуальные версии
FPC3.0.2release
Lazarus1.6.4release
MSE4.4.2release
fpGUI1.4.1release
наши спонсоры ;)