Директивы компилятора |
Директивы компилятора |
Altair |
28.01.2005 7:34
Сообщение
#1
|
Ищущий истину Группа: Модераторы Сообщений: 4 824 Пол: Мужской Реальное имя: Олег Репутация: 45 |
Директивы компилятора
Почему-то мало кто пользуется директивами компилятора в полном масштабе... Еще {$M} {$N} {$E} {$I} приходится видеть, но вот такие: {$ifdef}...{$else}...{$endif} - почти никогда; несмотря на то, что они открывают довольно широкие возможности для программиста, а именно: позволяют писать код, успешно компилируемый на разных компиляторах Паскаля, в том числе и 32 битных, включая FPC и TMT. Еще одно удобство на мой взгяд - широкие возможности при отладке приложений. Общий синтаксис этих команд таков: {$define <условный_символ>} - установить условный_символ. {$ifdef <условный_символ>} - код следующий после этой директивы компилируется только в том случае, если условный_символ был установлен. {$else} - эта директива обозначает начало альтернативного участка кода. {$endif} - ограничивает действие директив {$ifdef} и {$else}. Режимы компиляции. Отладка. Предположим, что в программе необходимо на этапе отладки выводить какие-то данные для тестирования алгоритма... Можно, конечно, в окончательном варианте кода закомментировать такие отладочные выводы, или удалить, но лучше заключить "отладочные операторы" в такую конструкцию, с использованием директив: Код {$define debug} var x:byte; begin x:=1; inc(x); {$ifdef debug} writeln(x); {$endif} end. Таким образом, при работе программы на экран будет выведено значение "2". Если отладку надо отменить, мы можем убрать символ "$" из директивы {$define debug} - и теперь это будет просто коментарий, и следовательно на экран ничего не будет выведено. Универсальность кода Хорошо, когда мы берем старый код из TP и он компилируется, и программа правильно работает в компиляторе постарше... А почему бы не реализовать совместимость наоборот или напрямую? Часто при компиляции, возникают ошибки только из-за того, что код оптимизирован под конкретный компилятор, например под BP, и в TP отказывается компилироваться... Выходом из такой ситуации является правильное написание кода, а именно отладка кода под различные компиляторы (конечно если это требуется). Для примера рассмотрим программу для построения графиков некоторых функций (в полярной системе координат) скачать архив {$ifdef Win32} Этот код можно скомпилировать вот в этих компиляторах: FPC(target: Win32, DOS), TP7, BP7, BPW (target:real, protected mode), TMT. Неплохо, правда? И везде он будет работать одинаково правильно! Конечно при компиляции в FPC под Win32, это будет windows приложение, а в остальных случаях консольное DOS (16 битное) приложение... Прокоментирую первые строчки программы (а дальше я думаю все понятно) Код {$ifdef Win32} {- если компилируем под Win32 } { (это срабтает только в FPC, TMT)} {$APPTYPE GUI} {- режим компиляции: графическое windows приложение.} {$else} {- компилируем в 16 битных компиляторах.} {$E+} {$N+} {-включаем эмуляцию сопсроцессора, т.к. в } { программе используются тип double} {$endif} {-конец условного участка кода.} Uses {$ifdef Win32} {-если компилируем под Win32 } WinCrt,Windows,{ подключаем соотв. модули.} {$else} {- иначе компиляция в 16 битных компиляторах} CRT, {$endif} {- конец условного куска кода.} Graph; {- а этот модуль подключается в любом случае.} Эмуляция сопроцессора Очень часто у многих возникает вопрос - почему при компиляции у меня возникает ошибка Error 116: Must be in 8087 mode to compile this. Ответ: Вы используете один из следующих вещественных типов: Single, Double, Extended, Comp Для работы с этими типами, необходима эмуляция сопроцессора. Просто добавьте в начало программы директивы: {$E+, $N+} Оптимизация Для уменьшения размера программ желательно добавить следующие директивы: {$B-} - быстрое вычисление логических условий; Но с оптимизацией будьте очень осторожны !! Например, вот такой пример будет компилироваться, но выдаст неверный результат (попробуйте запустить программу без ключей {$B-} и {$B+}...): Код var x, y: integer; function do_it: boolean; begin x := 5; { Здесь меняется значение глобальной переменной } do_it := true; end; begin x := 2; {$B-} if (x > 5) and do_it then y := x else y := 2 * x; {$B+} { При "быстром" вычислении логических условий результат будет неверный } writeln('y = ', y); writeln('x = ', x) end. Добавлено: Volvo {$D-} - отключить информацию для отладки (пропадает возможность отлаживать программу!!! (через F7)). При этом размер сократится на 100-150 байт... Описание других директив {$N+} - сопроцессор {$E+} - эмуляция сопроцессора {$I-} - отключение проверок ввода/вывода {$R-} - отключение проверок на границы массивов {$S-} - отмена проверки на переполнение стека {$Q-} - отмена проверок на границы типов (overflow, underflow) -------------------- Помогая друг другу, мы справимся с любыми трудностями!
"Не опускать крылья!" (С) |
Текстовая версия | 28.09.2024 18:59 |