Директива компилятора - $INCLUDE
Раздел Сокровищница |
В своей статье я писал про проблему, возникающую в 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; |
Данная директива не решает всех проблем, это ведь не аналог директивы #include из языка С. Например, С позволяет организовать видимость модулей на нескольких уровнях - например, если модуль B включает модуль С, то модуль А, подключив модуль В, получит в своё распоряжение также и данные из модуля С. В нашем случае это недоступно, однако часто это и не требуется. А вот сократить список uses в каждом файле проекта - это может быть полезно.