ЭЛЕКТРОННАЯ БИБЛИОТЕКА КОАПП
Сборники Художественной, Технической, Справочной, Английской, Нормативной, Исторической, и др. литературы.



 

Часть 7

                             ГЛАВА 6.

                       УПРАВЛЕНИЕ ПРОЕКТОМ.


     Вы уже  научились,  как писать программы на Turbo Pascal,  как
использовать стандартные  модули  и  как  писать  свои  собственные
модули.  Вы  уже  имеете  понятие  о том,  что программы могут быть
большими и разделяться на несколько файлов.  Как  управлять  такими
программами?
     В этой главе Вы получите знания, как объединить Вашу программу
в модули, как использовать встроенные возможности Make и Build, как
использовать условную  компиляцию  внутри  исходного  файла  и  как
оптимизировать Ваш код на скорость выполнения.


                       Организация программ.

     Turbo Pascal версии 6.0 позволяет разделить Вашу  программу на
кодовые сегменты.  Ваша главная программа после компиляции занимает
сегмент.  Это значит,  что она не может занимать памяти больше 64К.
Однако,   имеется   возможность   увеличить  этот  верхний  предел,
разбив Вашу программу на модули.  Каждый модуль может содержать  до
64К   машинных  кодов  при  компиляции.  Вопрос:  как  организовать
программу, как собрать ее в модули?
     Первое -   это   объединить   все   глобальные  определения  -
константы, типы данных,  переменные -  в  один  модуль.  Его  можно
назвать MyGlobals.  В отличие от включаемых файлов, модули не могут
"видеть" любые определения,  сделанные  в  главной  программе;  они
"видят" только   то,   что   определено  в  интерфейсной  части  их
собственного модуля и  в  других  модулях,  используемых  ими.  Ваш
модуль может использовать MyGlobals и обращаться ко всем глобальным
объявлениям.
     Второй возможный модуль - MyUtils. В этом модуле можно собрать
подпрограммы,  используемые в вашей программе.  Здесь  должны  быть
собраны подпрограммы ,  которые не зависят от каких-либо других (за
исключением других программ в MyUtils).
     Кроме этого   Вы  можете  объединить  процедуры  и  функции  в
логические группы.  В  каждой  группе  можно  определить  несколько
процедур  и  функций,  которые  наиболее  часто  используются Вашей
программой  и  затем  процедуры  и  функции,  которые  используются
несколько реже.  Подобные  группы  образуют прекрасный модуль.  Как
создать его:
     1. Скопируйте  все  эти процедуры и функции в отдельный файл и
удалите их из главной программы.
     2. Откройте этот файл для редактирования.
     3. Наберите следующие строки перед процедурами и функциями:

                         unit имя модуля;
                             intarface
                          uses MyGlobals
                          implementation

     где имя   модуля   -   имя   Вашего   модуля  (и  так  же  имя
редактируемого файла).
     4. Наберите оператор end,  в конце файла.
     5. Между  interface  и  implementation  скопируйте   заголовки
процедур и  функций,  вызываемых из главной программы.  Заголовок -
это первая строка подпрограммы  вместе  со  словами  procedure  или
function.
     6. Если этот модуль  использует  другие  модули,  заведите  их
имена,  отделяя запятыми между словом MyGlobals и ";" в предложении
Uses.
     7. Откомпилируйте этот файл.
     8. Вернитесь в Вашу главную программу  и  добавьте  имя  этого
модуля в предложение Uses.
     Это идеальный  вариант,  если  Вы  хотите  организовать   Вашу
программу таким   образом,  чтобы  она  удобно  модифицировалась  и
перекомпилировалась как можно быстрее.  И это наиболее важно, такая
оптимизация  дает  возможность работать с более компактными и легко
управляемыми кусками программных кодов.


                          Инициализация.

     Напомним, что  любой  модуль может иметь свои собственные коды
инициализации.   Они   выполняются   автоматически   при   загрузке
программы. Если  программа использует различные модули, выполняется
инициализационный код   каждого   из   них.   Порядок    выполнения
определяется  порядком  описания модулей в предложении Uses.  Итак,
если в программе описано:

               uses MyGlobal, MyUtils, EditLib, GraphLib;

     то секция  инициализации  MyGlobal   будет   вызвана   первой,
следующая - модуля MyUtils и т.д.
     Для создания раздела инициализации модуля  поместите  ключевое
слово begin перед словом end в конце раздела реализации.  Эти слова
определяют раздел  инициализации  модуля   аналогично   тому,   как
begin...end определяет главное тело программы,  процедуры, функции.
Вы можете поместить сюда любой код Паскаля. Здесь могут быть ссылки
на  все объявления этого модуля как из интерфейсного раздела, так и
из раздела реализации.  Здесь так же  могут  быть  ссылки  к  любым
объявлениям интерфейсных  частей  всех  модулей,  используемых этим
модулем.


                      Средства Build и Make.

     Turbo Pascal  включает  в  себя  очень  важное  и очень нужное
средство управления проектом - встроенную утилиту  Make. Рассмотрим
ее значение в системе.
     Допустим имеется  программа  MYAPP.PAS,   которая   использует
четыре модуля:  MyGlobals,  MyUtils,  EditLib, GraphLib. Эти четыре
модуля - четыре текстовых файла MYGLOBAL.PAS, MYUTILS.PAS, EDITLIB.
PAS,  GRAPHLIB.PAS. Далее MyUtils использует MyGlobаls, а EditLib и
GraphLib используют и MyGlobals и MyUtils.
     При компиляции  MYAPP.PАS  компилятор ищет файлы MYGLOBAL.TPU,
MYUTILS.TPU,  EDITLIB.TPU и GRAPHLIB.TPU,  загружает их  в  память,
собирает  их коды в файл MYAPP.PAS,  компилирует и записывает его в
файл MYAPP.EXE (если компилируется на диск).
     Теперь допустим, что мы внесем изменения в EDITLIB.PAS. Теперь
для создания MYAPP.EXE необходимо перекомпилировать и EDITLIB.PAS и
MYAPP.PAS. Это немного скучная, но не сложная задача.
     Допустим, изменения внесены в секцию  интерфейса MYGLOBАL.PAS.
Для  создания новой версии MYAPP.EXE,  необходимо перекомпилировать
уже все четыре модуля и сам MYAPP.PAS. Это означает, что при каждом
изменении в модуле MYGLOBAL.PAS, требуется перекомпиляция всех пяти
модулей.  Может показаться,  что использование  модулей  не  совсем
выгодно, однако не будем делать выводы.


                               Make.

     Turbo Pascal предлагает решение:  Вы можете использовать опцию
Make в  меню  Compile  и  Turbo  Pascal выполнит за Вас всю работу.
Процесс очень простой: после внесения изменений в какой-либо модуль
или  в  главную  программу  перекомпилировать  надо  только главную
программу.
     Turbo Pascal  осуществляет  три  вида  проверок:
     1. Во-первых,  проверка даты и  времени  для  каждого  модуля,
используемого  программой.  Дата  сверяется у файлов с расширениями
.PAS и .TPU. Если в файлы (.PAS) вносились изменения с тех пор, как
был    создан    соответствующий    .TPU,   то   этот   файл   .PAS
перекомпилируется заново, создавая обновленный файл .TPU. Поэтому в
первом  примере,  когда  изменения  вносятся  в EDITLIB.PAS,  Turbo
Pascal автоматически откомпилирует  EDITLIB.PAS  перед  компиляцией
MYAPP.PAS (при условии использования опции Make).
     2. Вторая  проверка:  были  ли  внесены  изменения  в   секцию
интерфейса   модифицируемого  модуля.  Если  это  имело  место,  то
Turbo Pascal заново от компилирует все модули,  использующие данный
модуль.
     Во втором  примере  изменения  внесены  в  раздел   интерфейса
MYGLOBАL.PAS,  модуль MYAPP.PAS компилируется заново.  Turbo Pascal
перед компиляцией MYAPP.PAS автоматически перекомпилирует MYGLOBAL.
PAS,  MYUTIL.PAS,  EDITLIB.PAS,  GRAPHLIB.PAS  (в  описанном в uses
порядке). Однако,  если Вы модифицировали только раздел реализации,
то перекомпиляция  других зависимых модулей не требуется, поскольку
(с их точки зрения) Вы не изменили этот модуль.

     3. Третья  проверка  касается  включаемых   и   .OBJ   файлов,
содержащих подпрограммы   на  Ассемблере,  используемых  каким-либо
модулем. Если данный файл .TPU создан раньше, чем какой-нибудь файл
включаемый  или .OBJ,  с которым он собирается,  то соответствующий
модуль компилируется  заново.  Таким  образом,  если  были  внесены
изменения в подпрограммах,  написанных на Ассемблере,  используемые
модулем, этот  модуль  автоматически  перекомпилируется,  когда  Вы
компилируете программу, использующую этот модуль.
     Для использования опции Makе, надо выбрать команду Make в меню
Compile или нажать F9.  При работе с компилятором командной строки,
укажите опцию /M. Опция Make не воздействует на модули, находящиеся
в TURBO.TPL.


                              Build.

     Опция Build - это частный случай Make. При использовании Build
перекомпилируются   все  модули,  используемые  данной  программой,
исключая модули  из  библиотеки  TURВО.TРL.  Это  более  простой  и
надежный способ, что все будет обновлено.
     Для вызова Build из командной строки используйте опоцию /B.


                     Автономная утилита Маkе.

     Turbo Pascal  предлагает  большой  набор  мощных  средств  для
управления и создания больших и сложных  программ,  построенных  из
многочисленных   модулей,  исходных  и  объектных  файлов.  Система
предлагает автоматическое  выполнение  операций   Make   и   Build,
перекомпилируя  модули  в  случае  необходимости.  В  то  же время,
Turbo Pascal не имеет средств для получения обновленных .OBJ файлов
(файлов объектных   кодов)   подпрограмм,   написанных   на   языке
Ассемблера (.ASM файлов), в случае модификации последних. Для этого
необходимо использовать отдельный Ассемблер.  Вопрос:  Как получить
последние версии файлов  с  расширениями  .ASM  и  .OBJ  и  как  их
подключать к программам?
     Ответ прост.  Используйте  автономную  утилиту  Make,  которая
поставляется вместе с системой Turbo Pascal .
     Make - интеллектуальный  программный  администратор,  который,
при  задании  определенных  команд,  выполнит необходимую работу по
сохранению и обновлению программ. На самом деле возможности утилиты
Make значительно шире. В ее функциональные возможности входит:

     - создание резервных копий;
     - удаление файлов из различных подсправочников;
     - автоматический  запуск  программ  с  внесением  изменений  в
используемые файлы данных .

     По мере изучения использования утилиты Make,  можно увидеть  и
другие возможности и способы применения этой утилиты для разработки
программного обеспечения.
     Make - автономная утилита; она отличается от опций Make Build,
которые включены в IDE и компилятор командной строки  (утилита Make
описана в Приложении А).


                         Небольшой пример.

     Допустим, надо  написать  несколько  программ,  выводящих   на
дисплей  некоторую  информацию о ближайших звездных системах.  Одна
программа GETSTAR.PAS считывает в текстовый  файл  список  звездных
систем, обрабатывает его и создает двоичный файл этой информации.
     GETSTAR.PAS использует  три  модуля:   STARDEFS.TPU,   который
содержит глобальные определения;  STARLIB.TPU, содержащий некоторые
утилиты  (вспомогательные  подпрограммы);   STARPROC.TPU,   который
делает  основную обработку информации.  Исходные коды их находятся,
соответственно, в файлах:

               STARDEFS.PAS, STARLIB.PAS, STARPROC.PAS

     Определим следующие зависимости:

     - STARDEFS.PAS не использует никаких других модулей;
     - STARLIB.PAS использует STARDEFS;
     - STARPROC.PAS использует STARDEFS и STARLIB;
     - GETSTAR.PAS использует STARDEFS, STARLIB и STARPROC.

     Для получения    GETSTAR.EXE   необходимо   просто   "сделать"
(откомпилировать) GETSTAR.PAS. Turbo Pascal будет перекомпилировать
модули по необходимости.
     Допустим, есть  несколько   подпрограмм   из   STARLIB.PAS   -
написаных на Ассемблере файлов SLIB1.ASM и SLIB2.ASM.  После работы
Turbo Assembler получаем файлы SLIB1.OBJ и  SLIB2.OBJ.  Каждый  раз
STARLIB.PAS  при  компиляции  компонуется  с  обоими  .OBJ файлами.
Фактически,  Turbo Pascal заново перекомпилирует STARLIB.PAS,  если
файл STARLIB.TPU создан раньше, чем какой-либо из этих .OBJ файлов.
     Что будет в случае,  если какой-либо из  .OBJ файлов  окажется
созданным  раньше,  чем  файлы  .ASM,  от которых они зависят?  Это
значит, что соответствующий файл с  расширением  .ASM  должен  быть
реассемблирован.  Turbo Pascal не может ассемблировать такие файлы.
Что же делать?
     Необходимо создать  командный  файл для Make,  вызвать утилиту
Make,  подав  ей  этот  командный  файл.  Этот  файл   состоит   из
зависимостей и  команд.  Зависимости  определяют зависимость файлов
друг от друга.  Команды указывают Make,  как создать данный файл из
других файлов.


                Создание командного файла для Make.

     Файл для Make в этом случае должен выглядеть:

   GETSTARS.EXE : GETSTARS.PAS STARDEFS.PAS STARLIB.PAS SLIB1.ASM\
                  SLIB2.ASM SLIB.OBJ SLIB2.OBJ TPC GETSTARS /M

   SLIB1.OBJ    : SLIB1.ASM
      TASM SLIB1.ASM SLIB1.OBJ

   SLIB2.OBJ    : SLIB2.ASM
     TASM SLIB2.ASM SLIB2.OBJ

     Несколько непонятно. Объясним:

     - Первые две строки поясняют Make, что GETSTARS.EXE зависит от
трех файлов написанных на Turbo Pascal;  двух файлов, написанных на
ассемблере; двух  .OBJ  файлов.  Обратный  слэш  (\) в конце первой
строки  -  символ  строки  продолжения,   т.е.   строка   оператора
продолжается далее.

     - Третья  строка  - указание Make,  как создается новая версия
GETSTARS.EXE. Заметим,  что для обработки GETSTARS.PAS используется
компилятор командной  строки и использует встроенное в Turbo Pascal
средство Make (параметр /M).

     - Следующие две строки (пустые строки игнорируются)  говорят о
том,  что  SLIB1.OBJ  зависит  от  SLIB1.ASM и о том,  как получить
SLIB1.OBJ.

     - Последние две  строки  определяют  зависимости  (для  одного
файла) и действие Make и SLIB.OBJ.


                        Использование Мake.

     Допустим, создан этот командный файл при помощи  встроенного в
интегрированную   среду   редактора   (или   же  каким-либо  другим
редактором), записан и сохранен в файле STARS.MAK. Его можно задать
командой :

               make -f STARS.MAK

     где -f  -  опция,  указывающая Make,  какой файл использовать.
Make обрабатывает этот файл с конца и до вершины  файла. Во-первых,
она проверяет даты SLIB2.OBJ и SLIB2.ASM, если SLIB2.OBJ старее, то
Make вызывает команду:

               TAMS SLIB2.ASM SLIB2.OBJ,

     которая ассемблирует  SLIB2.ASM   и   создает   новую   версию
SLIB2.OBJ.  Такие  же  действия  (проверка  даты и ассемблирование)
производятся с SLIB1.OBJ. В заключение, проверяются все зависимости
GETSTARS.EXE и, если необходимо, выполняется команда:

               tpc GETSTARS/M.

     Опция /M   указывает   Turbo  Pascal  использовать  внутреннюю
программу Make,   которая    просмотрит    все    связи,    включая
перекомпиляцию файла STARLIB.PAS,  если дата создания SLIB1.OBJ или
SLIB2.OBJ окажется более новой, чем дата создания STARLIB.TPU.


                       Условная компиляция.

     Для облегчения разработок,  Turbo Pascal версии 6.0 предлагает
условную компиляцию.  Это значит,  что Вы можете решать какие части
можно  компилировать, основываясь на опциях и определенных символах.
Для подробного ознакомления с условными директивами  компиляции см.
главу 21 "Директивы компилятора" Руководства программиста.
     Формат условных  директив  прост   и   аналогичен   директивам
компилятора:

               {$ директива аргумент}

     где директива обозначает директиву типа DEFINE,  IFDEF и т.п.,
аргумент - аргумент.  Заметим,  что между директивой  и  аргументом
должен  быть  разделитель (пробел или символ табуляции).  В таблице
6.1. приведены условные директивы.

            Таблица 6.1. Директивы условной компиляции.

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
{$DEFINE символ}     определяет символ для других директив

{$UNDEF символ}      удаляет определение символа

{$IFDEF символ}      если символ определен, то следующие за ним
                     команды компилируются

{$IFNDEF символ}     если символ не определен, то следующие за
                     ним команды компилируются

{$IFOPT  x+}         если директива допустима, то следующие за
                     ней команды компилируются

{$IFOPT  x-}         если директива недопустима, то следующие
                     за ней команды компилируются

{$ELSE}              если предыдущая директива IFxxx не дала
                     значение TRUE, то следующий за ней код
                     компилируется

{$ENDIF}             обозначает конец директивы IFxxx ... ELSE
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД


                     Директивы DEFINE и UNDEF.

     Эти директивы  проверяют,  определен  ли  некоторый символ или
нет. Эти  символы  определяются  директивой  DEFINE  и  отключаются
директивой  UNDEF  (Вы так же можете определить символы в командной
строке и в интегрированной среде).
     Для определения символа, вставьте директиву

               {$DEFINE символ}

     в свою   программу.   Символ   подчиняется   обычным  правилам
образования идентификаторов,  таким как длина, допустимые символы и
т.д. Например:

               {$DEFINE debug}

     Это является  определением  символа debug для оставшейся части
программы до тех пор пока не встретится директива:

               {$UNDEF debug}

     или не встретится end.
     Если символ не определен, то UNDEF ни на что не влияет.


                  Определение в командной строке.

     При работе с компилятором  командной  строки  (TPC.EXE)  можно
определить условные символы в самой командной строке.  TPC понимает
опцию /D,  за которой следует список символов, разделенных точкой с
запятой (;).

               tpc myprog /Ddebug;test;dump

     Здесь определены  символы  debug,  test  и  dump для программы
MYPROG.PAS. Заметим,  что  опция  /D  является   сводной,   поэтому
следующая строка аналогична предыдущей:

               tpc myprog /Ddebug/Dtest/Ddump


               Определение в интегрированной среде.

     Условные символы   можно   определить    с    помощью    опции
Options/Compiler/Conditional Defines.   Множество   символов  можно
определить, введя их в поле ввода,  разделив их  точкой  с  запятой
(;).  Синтаксис  такой  же,  как и в случае использования командной
строки.


                     Предопределенные символы.

     Помимо символов,  определенных в программах,  есть возможность
проверять некоторые символы, определяемые Turbo Pascal.
     В табл. 6.2. перечислены эти символы.

              Таблица 6.2. Предопределенные символы.

ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
VER60              Всегда определен (TP 4.0. определяет VER 4.0
                   и т.д.)

MSDOS              Всегда определен

CPU86              Всегда определен

CPU87              Определен, если присутствует во время компиляции
                   процессор 8087
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД


                           Символ VER60.

     Этот символ определен всегда в  Turbo  Pascal  6.0.  Например,
VER40  определен  в  версии  4.0  и  т.д.  Последующие версии будут
соответственно иметь вид:

     - VER65 для версии 6.5;
     - VER70 для версии 7.0.
     и т.д.

     Это позволит   создавать   исходные   коды,   совместимые    с
последующими версиями.


                      Символы MSDOS и CPU86.

     Эти символы  определены   всегда.   Символ   MSDOS   указывает
компиляцию по  управлением  операционной системы DOS.  Символ CPU86
означает,  что в компьютере используется  процессор  iAPx86  (8088,
8086, 80186, 80286, 80386 и 80486) Intel.
     Поскольку, в последующем  появятся  версии  Turbo  Pascal  для
других  операционных  систем  и  процессоров,  то  и  в  них  будут
аналогичные   символы,   определяющие   операционные   системы    и
процессоры.


                           Символ CPU87.

     Turbo Pascal версии 6.0 поддерживает операции  над  числами  с
плавающей  точкой двумя способами:  аппаратно и программно.  Если в
компьютере установлен математический сопроцессор  80х87,  то  можно
использовать стандарт  IEEE  для  чисел с плавающей точкой (Single,
Double, Extended,  Comp).  В этом случае Turbo Pascal  осуществляет
прямые обращения к математическому процессору.
     Если у  вас  нет  процессора  8087,  то   можно   использовать
стандартные IEEE  типы,  указав Turbo Pascal эмулировать 8087.  Так
же, вы можете использовать стандартный вещественный тип с плавающей
точкой,  тогда  Turbo Pascal будет поддерживать все операции с этим
типом данных.  С помощью директив $N и $E можно определить,  что вы
хотите использовать.
     При загрузке компилятора Turbo Pascal  осуществляется проверка
наличия 80х87.  Если  он  имеется,  определяется  символ  CPU87.  В
противном случае, не определяется. Поэтому в начале программы можно
поместить следующее:

{$N+}                    {Всегда используется стандарт IEEE}
{$IFDEF  CPU87}          {Если есть 80x87}
{$E+}                    {Нет, используется библиотека эмуляции}
{$ENDIF}


                    Cимволы IFxxx,ELSE и ENDIF.

     Смысл использования  условных  директив  в том,  что Вы можете
выбрать исходный код для компиляции, если какой-то символ определен
или неопределен, или если какая-то опция включена или выключена.
     Формат:

               {$IFxxx}
                 исходный код
               {$ENDIF}

     где IFxxx - это IFDEF,  IFNDEF или IFOPT,  за которым  следует
соответствующий   аргумент;   а  исходный  код  -  некоторая  часть
программы на Turbo Pascal.  Если выражение в директиве IFxxx  имеет
значение  True,  то исходный код компилируется.  В противном случае
пропускается и рассматривается как комментарий.
     Часто Вы  имеете  альтернативные  части  исходного кода.  Если
выражение  имеет  значение  True,  то  компилируется   одна   часть
программы, а если значение выражения - False,  то другая. Для этого
существует директива $ELSE:

               {$IFxxx}
                 исходный код А
               {$ELSE}
                 исходный код В
               {$ENDIF}

     В этом примере,  если выражение IFxxx - True, то компилируется
исходный  код  А,  иначе (False) исходный код В.  Отметим,  что все
директивы IFxxx должны быть  внутри  одного  и  того  же  исходного
файла,  то  есть  такой  ситуации:  начало  в одном файле - конец в
другом, быть не должно.
     Однако, между  директивами  IFxxx  могут  находится включаемые
файлы:

               {$IFxxx}
               {$I file1.pas}
               {$ELSE}
               {$I file2.pas}
               {$ENDIF}

     Таким образом, имеется возможность выбора среди альтернативных
включаемых файлов  в зависимости от некоторых условий.
     Допускаются вложенные директивы IFxxx...ENDIF:

               {$IFxxx}               {Первая IF директива}
               ...
               {$IFxxx}               {Вторая IF директива}
               ...
               {$ENDIF}               {Конец второй IF директивы}
               ...
               {$ENDIF}               {Конец первой IF директивы}



                     Директивы IFDEF и IFNDEF.

     Теперь Вы  знаете,  как  определить   символ   и   о   наличии
предварительно определенных символов. Директивы IFDEF и IFNDEF дают
возможность условной компиляции в зависимости от  того,  определены
некоторые символы или не определены.
     Этот пример уже встречался:

{$IFDEF CPU87}            {Если есть 80x87}
{$N+,E-}                  {Тогда используются коды для 80x87}
{$ELSE}                   {В противном случае}
{$N+,E+}                  {Используется библиотека программ
{$ENDIF}                            эмуляции}

     Вставка этих  директив  в  программу  означает  автоматическое
включение опции $N при наличии математического сопроцессора 8087 во
время компиляции программы. Важный момент:
     $N -  это  опция времени компиляции.  Если имеется сопроцессор
8087, то программа откомпилируется при включенной директиве  $N+  и
выключенной директиве $E-,  что означает выбор прямых вызовов 8087.
В противном случае программа будет компилироваться с $N+ и $Е+, т.е
используется библиотека программ эмуляции. В случае, если программа
компилируется на машине с сопроцессором 8087, то .ЕХЕ файл не может
быть запущен на машине без процессора 8087. Конечно, если программа
компилировалась с использованием директивы {$N+,E+},  то  ее  можно
запускать  на  любой  системе и использовать эмуляцию в том случае,
когда   аппаратное   обеспечение   8087   не   обнаружено.
     Другой распространенный  способ  использования этих директив -
при отладке.

     Например, в начале каждого модуля помещается код:

     {$IFDEF debug}
     {$D+,L+}
     {$ELSE}
     {$D-,L-}
     {$ENDIF}

     Если в начало программы поместить директиву

     {$DEFINE debug}

     и откомпилировать ее,  то полная отладочная  информация  будет
генерироваться компилятором   для   использования   со   встроенным
интегрированным  отладчиком   или   автономным   отладчиком   Turbo
Debugger.   Аналогично,  можно  определить  части  исходного  кода,
которые будут подключены к компиляции только при  отладке.  В  этом
случае пишется:

               {$IFDЕF debug}
                 исходные коды
               {$ENDIF}

     где исходные  коды  компилируются  только  тогда,  когда debug
определен в этой точке.


                         Директива IFOPT.

     Иногда бывает   необходимо   вставить   или  исключить  код  в
зависимости от того,  какие  опции  компилятора  выбраны  (проверка
диапазона,  вывода,  обработка  чисел  и  т.д).  В Turbo Pascal это
осуществляется при помощи директивы IFOPT:

               {$IFOPT x+}

               и

               {$IFOPT x-}

     где x - одна из опций компилятора: $А, $В, $D, $Е, $F, $G, $I,
$L, $N,  $O,  $R,  $S, $V, $X (см. главу 21 "Директивы компилятора"
Руководства  программиста).  В  первом  случае,   последующий   код
компилируется при соответствующей активизированной опции. Во втором
случае, если соответствующая опция не активизирована.

     Пример:

     var
     {$IFOPT N+}
         Radius,Circ,Area:double;
     {$ELSE}
         Radius, Circ, Area : real;
     {$ENDIF}

     Выбирается тип   данных   для   перечисленных   переменных   в
зависимости от поддержки процессора 8087.

     Альтернативный пример:

     Assign (F, FileName);
     Reset (F);
     {$IOFOPT I-}
     IOCheck;
     {$ENDIF}

     где, IOCheck  -  процедура  пользователя,   которая   получает
значение  IOResult  и  печатает в случае необходимости сообщение об
ошибке. При наличии  директивы  {$I+},  не  имеет  смысла  вызывать
IOCheck,  т.к.  при  обнаружении ошибки программа будет остановлена
раньше, чем будет обращение к IOCheck.


                    Оптимизация кода программы.

     Некоторые опции  компилятора  оказывают влияние как на размер,
так и на скорость выполнения программы.  Происходит это потому, что
в  зависимости  от  этих опций в программу вставляется код проверки
ошибок и их обработки.  Эти опции лучше использовать при разработке
программ.   В   окончательной  версии  их  рекомендуется  исключать
(уменьшается размер и сокращается время выполнения).  Ниже приведен
список  опций  и их значений,  которые используются для оптимизации
программы.
     - {$A+}   позволяет   выравнивать  переменные  и  типированные
константы на границу слова. Это обеспечивает более быстрый доступ к
памяти для систем 80х86. По умолчанию эта опция включена.

     - {$B-} устанавливает короткое вычисление булевских выражений.
Вырабатывается код времени выполнения, который может быть меньше, в
зависимости   от   построения  булевских  выражений.  По  умолчанию
используется опция {$B-}.

     - {$E-} отключает библиотеку  эмуляции  8087.  Это  заставляет
Turbo Pascal использовать либо сопроцессор 8087, либо стандартный 6
-ти байтный тип Real,  в зависимости от состояния  опции  {$N}.  По
умолчанию используется - {$E-}.

     - {$G-}   использует   дополнительные   инструкции  80286  для
улучшения генерируемого кода;  программа,  откомпилированная с этой
опцией не может выполняться на процессорах 8088 и 8086.

     - {$I-}  отключает  проверку  ошибок  ввода/вывода.  С помощью
вызова встроенной функции IOResult в программе,  можно обрабатывать
ошибки ввода/вывода самим. По умолчанию используется {$I+}.

     - {$N-}  генерирует  код  8087,  выполняющий  все  операции  с
плавающей точкой,  используя встроенный 6-байтовый тип Real.  Когда
эта  опция  включена,  будет  использоваться аппаратное обеспечение
8087 или программная эмуляция. Если Вы компилируете программу и все
модули, используя  {$N-},  библиотека  времени  выполнения  8087 не
требьуется и Turbo Pascal игнорирует директиву $E.  По умолчанию  -
{$N-}.

     - {$R-}  выключает  проверку диапазона.  При генерации кода не
осуществляется проверка  ошибок  в  индексировании  массивов  и  не
проверяется   принадлежность   присваиваемых  значений  допустимому
диапазону. По умолчанию эта опция отключена.

     - {$S-}  выключает  проверку  стека.  При  генерации  кода  не
проверяется наличие  достаточной  памяти  для  стека каждого вызова
процедуры или функции. По умолчанию эта опция отключена.

     - {$V-} отменяет проверку  параметров  var,  которые  являются
строками.   Это   позволяет   передавать   в  качестве  фактических
параметров строки, длина которых отлична от типа, определенного для
формального параметра var. По умолчанию эта опция включена.

     - {$X+}  разрешает  использовать вызовы функций как операторы;
результат вызова функции может быть отброшен.

     См. главу  21  Руководства  программиста  для   дополнительной
информации о директивах компилятора.

     Оптимизация кода   с   использованием  этих  опций  имеет  два
преимущества:

     - обычно уменьшает код и время выполнения;
     - позволяет избавиться от того, от чего обычно не избавиться.

     Однако, их    использование    означает   определенный   риск.
Пользоваться ими надо осторожно.  Если же  программа  поведет  себя
непонятно и непредсказуемо, то их следует включить вновь.
     Помимо возможности включения  этих  средств  в  исходный  код,
имеется возможность установить их с помощью меню Options/Compiler в
интегрированной среде или с помощью опции $X  в  командной  строке,
(где X - это соответствующая буква директивы компилятора).


Яндекс цитирования