Директива компилятора — INCLUDE

{codecitation class=»brush: pascal; gutter: false;» width=»600px»}

Оформил: DeeCo

Автор: Виктор Кода

В своей статье Пишем DirectX-движок я писал про проблему, возникающую в Object Pascal в связи с только явным подключением заголовочных файлов. Благодаря одному человеку, подсказавшему решение, для меня эта проблема в основом снята. Хочу поделиться решением.

Существует такая директива компилятора — {$INCLUDE filename} и её более короткий аналог {$I filename}. Раньше я недооценивал её значение, т. к. в чужих программах с помощью неё к коду программы подключались либо файлы с процедурами, либо списки ассемблерных команд. Выяснилось, что с помощью этой директивы можно подключать и ссылки на другие файлы программы. Поясню на примере.

В IDE Delphi 5 при создании нового проекта в интерфейсной секции автоматически формируется список uses такого вида:

uses

Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs;

Начинающие ещё не усматривают никакого подвоха в этом (как не замечал этого и я, когда только осваивал программирование), но постепенно с ростом программ список uses, помимо ссылок на стандартные файлы среды, начинает пополняться десятками собственных и грозит распухнуть до гигинтских размеров. Частично её можно решить, если весь код собрать в нескольких файлах, но это неудобно.

Выход один — можно создать отдельный файл — назовём его, например, vcl.pas. После этого модернизируем его так:

//——————————————————————

// Файл: vcl.pas

// Описание: Список ссылок на стандартные модули VCL

//——————————————————————

Windows,

Messages,

SysUtils,

Classes,

Graphics,

Controls,

Forms,

Dialogs

Замечу, здесь нет ошибки! Именно так, без всех зарезервированных слов языка, должен выглядеть этот файл. После Dialogs точка с запятой отсутствует.

Теперь в модуле Unit1.pas удаляем все ссылки и пишем:

uses

Activex, // для наглядности

{$I vcl};

Т. к. расширение по умолчанию — *.pas, его можно не указывать. Что же произошло? Директивой {$i} мы указали компилятору подставить список ссылок в текст модуля Unit1.pas. Получилось

uses

Activex,

Windows,

Messages,

SysUtils,

Classes,

Graphics,

Controls,

Forms,

Dialogs;

Если бы поставили запятую ранее, то получилось бы ,; — что недопустимо. Можно поставить точку с запятой в конце списка ссылок в файле vcl.pas, но тогда нельзя ставить этот символ после директивы. Просто уясните себе, что директива {$INCLUDE} подставляет в исходную программу блок строк из указанного файла, и код необходимо согласовать. Также необходимо помнить, что данный файл (vcl.pas) не должен быть подключен к проекту, другими словами, в файле проекта ссылка вроде

vcl in ‘vcl.pas’;

должна отсутствовать — иначе возникнет ошибка наподобие

[Error]vcl.pas(5): ‘UNIT’ expected but identifier ‘Windows’ found.

Данная директива не решает всех проблем, это ведь не аналог директивы #include из языка С. Например, С позволяет организовать видимость модулей на нескольких уровнях — например, если модуль B включает модуль С, то модуль А, подключив модуль В, получит в своё распоряжение также и данные из модуля С. В нашем случае это недоступно, однако часто это и не требуется. А вот сократить список uses в каждом файле проекта — это может быть полезно.

{/codecitation}

Добавить комментарий