$BoolEval — Директива компилятора Delphi


Язык Delphi для Win32 и. Net — синтаксис, операции, операторы

Название Язык Delphi для Win32 и. Net — синтаксис, операции, операторы
страница 2/11
Дата публикации 04.06.2013
Размер 1.12 Mb.
Тип Документы

litcey.ru > Информатика > Документы

^ 2.2.4 Ключевые директивы

В разд. 2.2.1 пояснялся синтаксис и назначение ключевых директив. В разд. 2.2.2 при описании настройки компилятора описаны многие ключевые опции. В данном разделе приводятся более подробные сведения по этим и по всем остальным ключевым директивам.

<$А±>, <$ALIGN>— директивы выравнивания полей записей

Директивы компилятора, включающие или выключающие выравнивание

Область действия локальная

Директивы включают или выключают выравнивание полей типов записей (см. разд. 4.4 и 7.1). Директивы <$А>обеспечивают выравнивание полей записей и классов, которые объявлены без модификатора packed. Это обеспечивает более быструю работу с записями и свойствами. При наличии директивы < $А->или <$А1>выравнивание полей никогда не происходит, как будто все поля packed. При <$А2>поля выравниваются по границам слов (word), при <$А4>— по границам удвоенных слов, при <$А8>или <$А+>по границам четырех слов.

Директивы выравнивания влияют только на поля записей и классов. Переменные и типизированные константы выравниваются всегда, независимо от директив выравнивания.

<$ASSERTIONS>— директивы проверки утверждений

См. «<$С>, <$ASSERTIONS>— директивы проверки утверждений».

<$В±>, <$BOOLEVAL>— директивы управления вычислением булевых выражений

Директивы компилятора, управляющие вычислением булевых выражений

^ По умолчанию <$ В->и л и

Область действия локальная

Компилятор Delphi поддерживает два режима вычисления булевых выражений, содержащих операции and и ог: полный и сокращенный (см. разд. 2.8.5). В режиме полного вычисления, который обеспечивается директивой <$В+>, все логическое выражение вычисляется до конца, даже если после вычисления первого операнда результат ясен. В режиме сокращенного вычисления, который обеспечивается включенной по умолчанию директивой <$В->, расчет прерывается, как только результат ясен. Например, операция ог дает результат true, если хотя бы один операнд равен true. Значит, если первый операнд равен true, то результат ясен и в режиме сокращенного вычисления расчет прервется без вычисления второго операнда. Это обеспечивает более быстрое выполнение, но при этом некоторые операнды могут оказаться не вычисленными. Например, если второй операнд — некоторая функция, возвращающая булево значение и кроме того вычисляющая что-то, необходимое для дальнейшего расчета, то при сокращенных вычислениях эти дополнительные расчеты могут не выполняться.

Директивы компилятора, разрешающие или запрещающие проверку утверждений

Область действия локальная

Директивы разрешают или запрещают проверку утверждений, влияют на работу процедуры Assert (см. разд. 2.3), используемой при отладке программ. По умолчанию действует директива <$С+>и процедура Assert генерирует исключение EAssertionFailed, если проверяемое утверждение ложно.

Так как эти проверки используются только в процессе отладки программы, то перед ее окончательной компиляцией следует указать директиву <$С->. При этом работа процедур Assert будет блокирована, и генерация исключений EAssertionFailed производиться не будет.

Директивы действуют на весь файл исходного кода независимо от того, в каком месте файла они расположены.

<$D±>, <$DEBUGINFO>— директивы отладочной информации

Директивы компилятора, управляющие включением в модуль отладочной информации

Область действия локальная

Директива < $D+>включает в генерируемый модуль отладочную информацию, позволяющую производить отладку по шагам, вводить в код точки прерывания и генерировать информацию о локальных символах. Отладочная информация увеличивает размер модуля и требует дополнительной памяти.

<$DEFINITIONINFO>— директивы генерации ссылок на символы

<$DENYPACKAGEUNIT>— директивы включения модуля в пакет

Директивы компилятора, запрещающие или разрешающие включение модуля в пакет

Область действия локальная

Директива <$DENYPACKAGEUNIT ON>не позволяет включить тот модуль, в котором она записана, в пакет.

<$DESIGNONLY>— директивы компиляции пакета

Директивы компилятора, управляющие компиляцией пакета для установки в среде Delphi

Область действия локальная

Директива <$DESIGNONLY ON>включается в модуль пакета (только в файл .dpk), когда он должен компилироваться для установки в Интегрированной Среде Разработки Delphi.

<$EXTENDEDSYNTAX>— директивы расширенного синтаксиса

См. «<$Х>, <$EXTENDEDSYNTAX>— директивы расширенного синтаксиса».

<$G±>, <$IMPORTEDDATA>— директивы управления импортируемыми данными

Директивы компилятора, управляющие импортом данных

Область действия локальная

Директива <$G->или <$IMPORTEDDATA OFF>запрещает создание ссылок на импортируемые данные.

Директивы компилятора, определяющие значение типа строк string

Область действия локальная

Директивы определяют, какому типу соответствует ключевое слово string. При директиве <$Н+>это ключевое слово соответствует длинным динамически размещаемым в памяти строкам AnsiString. С этой директивой компилированы все компоненты библиотеки Delphi и с ней же должны компилироваться новые компоненты, создаваемые пользователем.

При директиве <$Н->тип string соответствует коротким статически размещаемым строкам ShortString или string[255]. Это используется в основном при заимствовании кодов из ранних версий Delphi.

<$HINTS>— директивы управления замечаниями компилятора

Директивы компилятора, включающие и выключающие выдачу замечаний

Область действия локальная

Директивы включают или выключают генерацию замечаний компилятора о неиспользуемых переменных, неиспользуемых присваиваниях, никогда не выполняемых циклах for и while и т.п. Если вы хотите в каком-то фрагменте кода выключить генерацию таких замечаний, это надо оформить следующим образом:

Тогда по отношению к этому фрагменту не будут делаться замечания, например, об объявленных, но не используемых переменных.

Директивы компилятора, включающие и выключающие контроль файлового ввода-вывода

Область действия локальная

Директивы включают или выключают автоматический контроль результата вызова процедур ввода-вывода. Если действует директива <$1+>, то при возвращении процедурой ввода-вывода ненулевого значения генерируется исключение EInOutError и в его свойство errorcode заносится код ошибки. Таким образом, при действующей директиве <$1+>операции ввода-вывода располагаются в блоке try. except (см. разд. 3.2.7), имеющем обработчик исключения EInOutError. Если такого блока нет, то обработка производится методом TApplication.HandleException.

Если действует директива <$1->, то исключение не генерируется. В этом случае проверить, была ли ошибка, или ее не было, можно, обратившись к функции IOResult. Эта функция очищает ошибку и возвращает ее код, который затем можно анализировать. Типичное применение директивы <$1->и функции IOResult демонстрирует следующий пример (сработает только в приложении VCL Win32):

В этом примере на время открытия файла отключается проверка ошибок ввода вывода, затем она опять включается, переменной i присваивается значение, возвращаемое функцией IOResult и, если это значение не равно нулю (есть ошибка), то предпринимаются какие-то действия в зависимости от кода ошибки.

Подобный стиль программирования был типичен до введения в язык Delphi механизма обработки исключений. Однако сейчас подобный стиль устарел и применение директив $1 потеряло былое значение, все более уступая место обработке исключений (см. разд. 3.2).

Директивы компилятора, разрешающие или запрещающие перекомпиляцию

Область действия глобальная

Директивы разрешают или запрещают перекомпиляцию модуля. Запрещать перекомпиляцию имеет смысл в случаях, если перекомпиляция данного модуля должна быть проведена позднее.

<$IMPORTEDDATA>— директивы управления импортируемыми данными

См. «<$G>, <$IMPORTEDDATA>— директивы управления импортируемы-

<$INLINE>— директива встраиваемых функций

Директивы компилятора, определяющие, обработку встраиваемых функций

Область действия локальная

Директива <$INLINE>управляет созданием встраиваемых функций inline (см. разд. 2.7.5.).

Значение <$INLINE ON>, принятое по умолчанию, означает, что функции с директивой inline будут по возможности реализованы как встраиваемые. Значение <$INLINE AUTO>аналогично предыдущему, но дополнительно будут сделаны встраиваемыми все функции, размер которых меньше 32 байт, даже если в их объявлении нет директивы inline. Значение <$INLINE OFF>исключает реализацию встраиваемых функций, игнорируя директиву inline.

<$IOCHECKS>— директива контроля ввода-вывода

См. «<$1±>, <$IOCHECKS>— директивы контроля ввода-вывода»

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

Область действия локальная

В ранних версиях Delphi и Borland Pascal значения всех типизированных констант можно было менять. Поэтому прежние коды, использующие эти возможности, следует компилировать с директивой <$J+>, разрешающей изменять типизированные константы. Однако, новые приложения следует компилировать с директивой <$J->, при которой типизированные константы — действительно константы и попытка их изменения вызовет сообщение компилятора об ошибке.

<$L±>, <$LOCALSYMBOLS>— директивы, управляющие информацией о локальных символах

Директивы компилятора, разрешающие или запрещающие генерацию ин-

информации о локальных символах

Область действия глобальная

Директивы разрешают или запрещают генерацию информации о локальных символах. Информация включает имена и типы всех локальных переменных и констант модуля. Это увеличивает объем модуля и замедляет компиляцию, но зато позволяет в процессе отладки просматривать и модифицировать локальные переменные, а также дает возможность просматривать последовательность вызовов функций и процедур командой View | Debug Windows | Call Stack. Включение директивы $L позволяет также для проекта VCL Win32 включать опции Include TDW debug info и Map file на странице Linker диалогового окна, вызываемого командой Project | Options.

Директива $L обычно включается и выключается синхронно с директивой $D. В частности, директива $L игнорируется, если используется директива <$D->.

<$LONGSTRINGS>— директивы задания типа строк

См. «<$Н>, <$LONGSTRINGS>— директивы задания типа строк».

<$М±>, <$TYPEINFO>— директивы информации времени выполнения о типах

Директивы компилятора, включающие и выключающие генерацию инфор-

информации времени выполнения о типах (runtime type information — RTTI)

Область действия локальная

Директивы включают или выключают генерацию информации времени выполнения о типах (runtime type information — RTTI). Если класс объявляется в состоянии < $М+>или является производным от класса, объявленного в этом состоянии, то компилятор генерирует RTTI о его полях, методах и свойствах, объявленных в разделе published. В противном случае раздел published в классе не допускается.

Класс TPersistent, являющийся предшественником большинства классов Delphi и всех классов компонентов, объявлен в модуле Classes в состоянии <$М+>. Так что для всех классов, производных от него, заботиться о директиве <$М+>не приходится.

<$ MESS AGE>— директива генерации сообщения

Директива генерирует сообщение, подобное сообщениям компилятора

^ Область действия локальная

Директива обеспечивает во время компиляции генерацию сообщения с заданным текстом, подобного сообщениям компилятора. Необязательный второй параметр директивы может отсутствовать, или принимать значение HINT, WARN, ERROR или FATAL. Это значение просто определяет, с какой пометкой будет выдано сообщение.

Директиву удобно применять совместно с директивами условной компиляции (см. разд. 2.2.3). Тогда вы будете сразу видеть, какой вариант приложения вы скомпилировали. Например:

В результате компиляции вы получите сообщение вида:

[Hint] Unit2.pas(89): Н2428 Сгенерирован код без отладочной печати

Если вы зададите в директиве параметр HINT, то результат будет тот же. А если вы зададите параметр WARN:

$BoolEval — Директива компилятора Delphi

Есть ли в Delphi 7 директива компилятору по обработке исключений, регулируемых в процессе отладки галочкой Stop on Delphi Exception?

справку по директивам компилятора почитать не ?


> справку по директивам компилятора почитать не ?

зачем читать если можно спросить и заниматься своими делами. Но у меня, честно говоря, просто не было времени выяснять. А вообще я за RTFM


> зачем читать если можно спросить и заниматься своими делами

разумный подход, черт побери.


> зачем читать если можно спросить и заниматься своими делами.

Если эту логику чуть дальше развернуть, то получится, что зачем вообще работать? На этом форуме спрошу как делать это, на другом — как другое, на третьем — третье. А сам буду на диване лежать и фапать в потолок.

Что-то я не понял о чем речь?
Какая связь между директивами компилятора и поведением отладчика?

> Ega23 (15.04.2010 00:01:04) [4]

Остался один не достаток, спрашивать надо, бот бы еще без этого.

вот вы любители пофлеймить, дай только причину )))
ладно, шучу. Мануал так и не читал, потому что нет времени пока.

Проблема в том что мне надо в процессе отладки какого то алгоритма, видеть экцепшены, а некая логика завязана на них, то есть если я включу их индикацию то я буду ловить в отладчике все исключения, и зря останавливаться на тех, которые я ловлю в секциях try except. Вернее я их все ловлю но, определённого типа исключения я ловлю в циклах, а других типов только единожды. Вот если бы как то включить одни типы, а выключить другие — было бы круто!


> Константин (17.04.10 13:10) [7]


> было бы круто!

все и так круто.. заходим в опции дельфи и там находим что-то типа
Debugger Options -> Language Exception

> Константин (17.04.2010 13:10:07) [7]

Мануал все таки читай. Времени для этого более чем достаточно, программировать пока не надо.

$BoolEval — Директива компилятора Delphi

<$I+>и <$I->— директивы контроля ввода/вывода <$M>и <$S>— директивы, определяющие размер стека <$M+>и <$M->— директивы информации времени выполнения о типах <$Q+>и <$Q->— директивы проверки переполнения целочисленных операций <$R>— директива связывания ресурсов <$R+>и <$R->— директивы проверки диапазона <$APPTYPE CONSOLE>— директива создания консольного приложения 1) Директивы компилятора, разрешающие или запрещающие проверку утверждений. По умолчанию <$C+>или <$ASSERTIONS ON>Область действия локальная Директивы компилятора $C разрешают или запрещают проверку утверждений. Они влияют на работу процедуры Assert,используемой при отладке программ. По умолчанию действует директива <$C+>и процедура Assert генерирует исключение EAssertionFailed, если проверяемое утверждение ложно. Так как эти проверки используются только в процессе отладки программы, то перед ее окончательной компиляцией следует указать директиву <$C->.

Директивы Компилятора-Версии Delphi

у меня есть единица, которую я написал в Delphi 7 некоторое время назад, и только что получил удовольствие (боль) от преобразования в Delphi XE (Unicode).

устройство отлично работает после некоторых проблем, теперь я пытаюсь сделать это устройство совместимым с различными версиями Delphi, если мне когда-либо понадобится переключить IDE обратно на Delphi 7 при обновлении другого кода.

У меня есть только Delphi 7 и Delphi XE, но из того, что я собираю код, написанный на Delphi 1 в Delphi 2007, будет компилироваться, но код из Delphi 2009 и выше будет Unicode.

. Во всяком случае, в блоке я разделяю не-unicode и unicode следующим образом:

Как изменить директиву компилятора, чтобы правила применялись к нескольким версиям? Например что-то вроде:

это будет охватывать все версии Delphi, если я распространю источник или .блок УЗК.

2 ответов

интересно, Самый простой подход в этом случае-переключить поведение на UNICODE условное. Это условие определяется тогда и только тогда, когда вы используете версию Delphi в Юникоде, т. е. в Delphi 2009 и более поздних версиях. Большим преимуществом этого является то, что это будущее-вам не нужно обновлять код каждый раз, когда выходит новый Делфи. Более того, условный переключатель будет гораздо более читаемым, поскольку он будет четко выражать намерение.

Delphi документация имеет отличный темы список всех предопределенных условий. Полный список условий версии также связан оттуда.

Директива компилятора Delphi для оценки аргументов в обратном порядке

Я был очень впечатлен этим delphi двумя лайнерами, используя функцию IFThen из Math.pas. Однако сначала он оценивает DB.ReturnFieldI, что является неудачным, потому что мне нужно вызвать DB.first, чтобы получить первую запись.

(как бессмысленное разъяснение, потому что у меня уже есть много хороших ответов. Я забыл упомянуть, что 0 — это код, который DB.First возвращает, если он что-то получил в нем, возможно, не имел смысла в противном случае)

Очевидно, это не такая уж большая проблема, как я мог бы заставить ее работать с пятью прочными лайнерами. Но все, что мне нужно для этого, — это использовать Delphi для оценки DB.first сначала и DB.ReturnFieldI. Я не хочу менять math.pas, и я не думаю, что это гарантирует мне перегрузку, потому что там, как 16 функций.

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

4 ответа

12 Решение Rob Kennedy [2010-06-16 18:47:00]

Обычно порядок оценки выражений undefined. (C и С++ аналогичны. Java всегда оценивает слева направо.) Компилятор не контролирует его. Если вам нужно два выражения для оценки в определенном порядке, напишите свой код по-разному. Я бы не стал беспокоиться о количестве строк кода. Линии дешевы; используйте столько, сколько вам нужно. Если вы часто используете этот шаблон, напишите функцию, которая завершает все:

Ваш исходный код, вероятно, не был бы тем, что вы хотели, даже если порядок оценки был другим. Даже если DB.First не был равен нулю, вызов ReturnFieldI все равно будет оцениваться. Все фактические параметры полностью вычисляются перед вызовом функции, которая их использует.

Изменение Math.pas все равно не поможет. Он не контролирует, в каком порядке оцениваются его фактические параметры. К тому времени, когда он их видит, они уже были оценены до логического значения и целого числа; они больше не являются исполняемыми выражениями.

Вызывающее соглашение может повлиять на порядок оценки, но по-прежнему нет гарантии. Порядок, в который вставляются параметры в стек, не обязательно должен соответствовать порядку, в котором эти значения были определены. Действительно, если вы обнаружите, что stdcall или cdecl дает вам желаемый порядок оценки (слева направо), тогда они оцениваются в обратном порядке того, с которым они были переданы.

Соглашение о вызове pascal передает аргументы слева направо в стеке. Это означает, что самый левый аргумент находится в нижней части стека, а самый правый аргумент находится вверху, чуть ниже адреса возврата. Если функция IfThen использовала этот вызов, существует несколько способов, которыми компилятор мог бы достичь этого макета стека:

То, как вы ожидаете, это то, что каждый аргумент оценивается и сразу же перенаправляется:

Оцените аргументы справа налево и сохраните результаты во временном режиме до тех пор, пока они не будут нажаты:

Сначала выделите пространство стека и оцените в любом порядке:

Обратите внимание, что IfThen принимает значения аргументов в том же порядке во всех трех случаях, но функции не обязательно вызывают в этом порядке.

Соглашение о вызове по умолчанию также передает аргументы слева направо, но первые три аргумента, которые соответствуют, передаются в регистры. Однако регистры, используемые для передачи аргументов, также являются реестрами, наиболее часто используемыми для оценки промежуточных выражений. Результат DB.First = 0 необходимо было передать в регистр EAX, но компилятор также нуждался в этом регистре для вызова ReturnFieldI и для вызова First . Вероятно, было бы гораздо удобнее сначала оценить вторую функцию, например:

Еще одно замечание: ваш первый аргумент является составным выражением. Там вызов функции и сравнение. Там нечего гарантировать, что эти две части выполняются последовательно. Компилятор может сначала вызвать вызовы функций, вызвав First и ReturnFieldI , а затем сравните возвращаемое значение First с нулем.

соглашение о вызове влияет на способ их оценки.
Для этого не существует компилятора.

Pascal — это вызов, который вы должны использовать для получения этого поведения.

Хотя я лично никогда не буду зависеть от этого типа поведения.

В следующей примерной программе показано, как это работает.

Это потребует от вас написать свои собственные функции IfThen.

Если вы действительно хотите, чтобы это был один лайнер, вы действительно можете это сделать в Delphi. Я просто думаю, что это выглядит уродливо.

1 philnext [2010-06-16 18:36:00]

Не можете ли вы изменить свой запрос, чтобы иметь только один результат, чтобы избежать команды «Первый»? Также как:

0 [2010-06-16 18:37:00]

AFAIK нет директивы компилятора для управления этим. Если вы не используете соглашения stdcall/cdecl/safecall, параметры передаются слева направо в стеке, но поскольку соглашение по регистру по умолчанию может также передавать параметры в регистрах, может случиться так, что параметр будет вычисляться позже поместить в регистр перед вызовом. И поскольку только фиксированный порядок фиксирован (EAX, EDX, ECX) для параметров, которые соответствуют критериям, регистры могут быть загружены в любом порядке. Вы могли бы попытаться принудительно использовать соглашение о вызове «pascal» (в любом случае вам нужно будет переписать функцию), но IMHO всегда опасно полагаться на такой код, если компилятор не может явно гарантировать порядок оценки. И введение порядка оценки может значительно уменьшить количество доступных оптимизаций.

Delphi Директива компилятора для оценки аргументов в обратном

Я был действительно впечатлен этим Дельфи два лайнера с помощью функции IFThen из Math.pas. Тем не менее, оценивает DB.ReturnFieldI первое, что прискорбно, потому что мне нужно вызвать DB.first, чтобы получить первую запись.

(Как бессмысленное разъяснение, потому что у меня так много хороших ответов уже. Я забыл упомянуть, что 0 это код, который DB.First возвращается, если у него есть что-то в нем, не могу иметь смысла в противном случае)

Очевидно, что это не такая большая проблема, как я мог заставить его работать с пятью прочными прокладками. Но все, что мне нужно для этого, чтобы работать для Delphi, чтобы оценить DB.first первый и второй DB.ReturnFieldI. Я не хочу, чтобы изменить math.pas, и я не думаю, что это гарантирует мне сделать перегруженную ifthen, потому что как 16 ifthen функций.

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

Порядок вычисления выражений обычно не определено . (C и C ++ является таким же образом. Java всегда вычисляется слева направо.) Компилятор не предлагает никакого контроля над ним. Если вам нужно два выражения должны быть оценены в определенном порядке, а затем написать свой код по- разному. Я бы не беспокоиться о количестве строк кода. Линии дешевы; использовать столько , сколько нужно. Если вы будете использовать этот шаблон часто, написать функцию , которая оборачивает все это:

Ваш исходный код , вероятно , не было бы то , что вы хотели, даже если порядок оценки были разными. Даже если DB.First не равен нулю, то вызов ReturnFieldI будет по- прежнему будет оцениваться. Все фактические параметры полностью оценены перед вызовом функции , которая использует их.

Изменение Math.pas не все равно поможет. Он не контролирует, в каком порядке его фактические параметры вычисляются в К тому времени он видит их, они уже были оценены до логического значения и целое. они не исполняемое выражения больше.

Соглашение о вызовах может повлиять на порядок оценки, но до сих пор нет гарантии. Порядок , в котором параметры помещаются в стек не должен совпадать с порядком , в котором были определены эти значения. В самом деле, если вы обнаружите , что STDCALL или Cdecl дает Вам желаемый порядок оценки (слева направо), то они оцениваются в обратном порядке по одному они прошли с.

Паскаль соглашение о вызовах передает аргументы влево-вправо на стеке. Это означает , что крайний левый аргумент один в нижней части стека, а крайний правый аргумент в верхней, чуть ниже обратного адреса. Если IfThen функция используется , что соглашение о вызове, есть несколько способов , компилятор может достичь этого макета стека:

То, как вы ожидаете, что это то, что каждый аргумент вычисляется и толкнул сразу:

Оценивать аргументы справа налево и сохранить результаты в временных, пока они не толкнули:

Выделяют пространство стека первым, и оценить в любом порядке, удобно:

Обратите внимание , что IfThen получает значение аргументов в том же порядке , во всех трех случаях, но эти функции не обязательно вызывается в таком порядке.

Регистр по умолчанию соглашение о вызовах также передает аргументы влево-вправо, но первые три аргумента , которые соответствуют передаются в регистрах. Регистры , используемые для передачи аргументов, хотя, также регистры , наиболее часто используемые для оценки промежуточных выражений. Результат DB.First = 0 должен был быть передан в регистр EAX, но компилятор также нужен этот регистр для вызова ReturnFieldI и для вызова First . Вероятно , это был немного более удобным , чтобы оценить вторую функцию первой, как это:

Еще одна вещь , чтобы указать на то , что ваш первый аргумент является выражение соединения. Там есть вызов функции и сравнение. Там нет ничего , чтобы гарантировать , что эти две части выполняются последовательно. Компилятор может получить вызовы функций из пути первого по телефону First и ReturnFieldI , а потом сравнить First возвращаемое значение от нуля.

Директивы и их описание

директивы условной компиляции
<$C+>и <$C->— директивы проверки утверждений
<$I+>и <$I->— директивы контроля ввода/вывода
<$M>и <$S>— директивы, определяющие размер стека

<$M+>и <$M->— директивы информации времени выполнения о типах
<$Q+>и <$Q->— директивы проверки переполнения целочисленных операций

<$R>— директива связывания ресурсов

<$R+>и <$R->— директивы проверки диапазона

<$APPTYPE CONSOLE>— директива создания консольного приложения

1) Директивы компилятора, разрешающие или запрещающие проверку утверждений.

По умолчанию <$C+>или

Область действия локальная

Директивы компилятора $C разрешают или запрещают проверку утверждений. Они влияют на работу процедуры Assert,используемой при отладке программ. По умолчанию действует
директива <$C+>и процедура Assert генерирует исключение EAssertionFailed, если проверяемое утверждение ложно.

Так как эти проверки используются только в процессе отладки программы, то перед ее окончательной компиляцией следует указать директиву <$C->. При этом работа процедур Assert будет блокировано и генерация исключений EassertionFailed производиться не будет.

Директивы действуют на весь файл исходного кода независимо от того, в каком месте файла они расположены.

2) Директивы компилятора, включающие и выключающие контроль файлового ввода-вывода.

По умолчанию <$I+>или

Область действия локальная

Директивы компилятора $I включают или выключают автоматический контроль результата вызова процедур ввода-вывода Object Pascal. Если действует директива <$I+>, то при возвращении процедурой ввода-вывода ненулевого значения генерируется
исключение EInOutError и в его свойство errorcode заносится код ошибки. Таким образом, при действующей директиве <$I+>операции ввода-вывода располагаются в блоке try. except, имеющем обработчик исключения EInOutError. Если такого блока нет, то обработка производится методом TApplication.HandleException.

Если действует директива <$I->, то исключение не генерируется. В этом случае проверить, была ли ошибка, или ее не было, можно, обратившись к функции IOResult. Эта функция очищает ошибку и возвращает ее код, который затем можно анализировать. Типичное применение директивы <$I->и функции IOResult демонстрирует следующий пример:

В этом примере на время открытия файла отключается проверка ошибок ввода вывода, затем она опять включается, переменной i присваивается значение, возвращаемое функцией IOResult и, если это значение не равно нулю (есть ошибка), то предпринимаются какие-то действия в зависимости от кода ошибки. Подобный стиль программирования был типичен до введения в Object Pascal механизма обработки исключений. Однако сейчас, по-видимому, подобный стиль устарел и применение директив $I потеряло былое значение.

3) Директивы компилятора, определяющие размер стека

Область действия глобальная

Локальные переменные в процедурах и функциях размещаются в стеке приложения. При каждом вызове процедуры или функции ее локальные переменные помещаются в стек. При выходе из процедуры или функции эти локальные процедуры удаляются из стека.
Директивы компилятора $M задают параметры стека приложения: его минимальный и максимальный размеры. Приложение всегда гарантировано имеет размер стека, равный его минимальной величине. Если при запуске приложения Windows обнаруживает, что не может
выделить этот минимальный объем памяти, то выдается сообщение об этой ошибке.

Если во время работы выясняется, что минимального размера стека не хватает, то размер увеличивается на 4 K, но не более, чем до установленного директивой максимального размера. Если увеличение размера стека невозможно из-за нехватки памяти или из-за достижения его максимальной величины, генерируется исключение EStackOverflow. Минимальный размер стека по умолчанию равен 16384 (16K). Этот размер может изменяться параметром minstacksize
директивы <$M>или параметром number директивы <$MINSTACKSIZE>.

Максимальный размер стека по умолчанию равен 1,048,576 (1M). Этот размер может изменяться параметром maxstacksize директивы <$M>или параметром number директивы <$MAXSTACKSIZE number>. Значение минимального размера стека может задаваться целым числом в диапазоне между1024 и 2147483647. Значение максимального размера стека должно быть не менее минимального размера и не более 2147483647. Директивы задания размера стека могут включаться только в программу и не должны использоваться в библиотеках и модулях.

В Delphi 1 имеется процедура компилятора <$S>, осуществляющая переключение контроля переполнения стека. Теперь этот процесс полностью автоматизирован и директива <$S>оставлена только для обратной совместимости.

4) Директивы компилятора, включающие и выключающие генерацию информации времени выполнения о типах (runtime type information — RTTI).

По умолчанию <$M->или

Область действия локальная

Директивы компилятора $I включают или выключают генерацию информации времени выполнения о типах (runtime type information — RTTI). Если класс объявляется в состоянии <$M+>или является производным от класса объявленного в этом состоянии, то компилятор генерирует RTTI о его полях, методах и свойствах, объявленных в разделе published. В противном
случае раздел published в классе не допускается. Класс TPersistent, являющийся предшественником большинства классов Delphi и все классов компонентов, объявлен в модуле Classes в состоянии <$M+>. Так что для всех классов, производных от него, заботиться о директиве <$M+>не приходится.

5) Директивы компилятора, включающие и выключающие проверку переполнения при целочисленных операциях

По умолчанию <$Q->или

Область действия локальная

Директивы компилятора $Q включают или выключают проверку переполнения при целочисленных операциях. Под переполнением понимается получение результата, который не может сохраняться в регистре компьютера. При включенной директиве <$Q+>проверяется переполнение при целочисленных операциях +, -, *, Abs, Sqr, Succ, Pred, Inc и Dec. После каждой из этих операций размещается код, осуществляющий соответствующую проверку. Если обнаружено переполнение,
то генерируется исключение EIntOverflow. Если это исключение не может быть обработано, выполнение программы завершается.

Директивы $Q проверяют только результат арифметических операций. Обычно они используются совместно с директивами <$R>, проверяющими диапазон значений при присваивании.
Директива <$Q+>замедляет выполнение программы и увеличивает ее размер. Поэтому обычно она используется только во время отладки программы. Однако, надо отдавать себе отчет, что отключение этой директивы приведет к появлению ошибочных результатов расчета в случаях, если переполнение действительно произойдет во время выполнении программы. Причем сообщений о подобных ошибках не будет.

6) Директива компилятора, связывающая с выполняемым модулем файлы ресурсов

Область действия локальная

Директива компилятора <$R>указывает файлы ресурсов (.DFM, .RES), которые должны быть включены в выполняемый модуль или в библиотеку. Указанный файл должен быть файлом ресурсов Windows. По умолчанию расширение файлов ресурсов — .RES. В процессе компоновки компилированной программы или библиотеки файлы, указанные в директивах <$R>, копируются в
выполняемый модуль. Компоновщик Delphi ищет эти файлы сначала в том каталоге, в котором расположен модуль, содержащий директиву <$R>, а затем в каталогах, указанных при выполнении команды главного меню Project | Options на странице Directories/Conditionals диалогового окна в опции Search path или в опции /R командной строки DCC32.

При генерации кода модуля, содержащего форму, Delphi автоматически включает в файл .pas директиву <$R *.DFM>, обеспечивающую компоновку файлов ресурсов форм. Эту директиву нельзя удалять из текста модуля, так как в противном случае загрузочный модуль не будет создан и генерируется исключение EResNotFound.

7) Директивы компилятора, включающие и выключающие проверку диапазона целочисленных значений и индексов

По умолчанию <$R->или

Область действия локальная

Директивы компилятора $R включают или выключают проверку диапазона целочисленных значений и индексов. Если включена директива <$R+>, то все индексы массивов и строк и все присваивания скалярным переменным и переменным с ограниченным диапазоном значений проверяются на соответствие значения допустимому диапазону. Если требования
диапазона нарушены или присваиваемое значение слишком велико, генерируется исключение ERangeError. Если оно не может быть перехвачено, выполнение программы завершается.

Проверка диапазона длинных строк типа Long strings не производится.
Директива <$R+>замедляет работу приложения и увеличивает его размер. Поэтому она обычно используется только во время отладки.

8) Директива компилятора, связывающая с выполняемым модулем файлы ресурсов

Область действия локальная

Директива компилятора <$R>указывает файлы ресурсов (.DFM, .RES), которые должны быть включены в выполняемый модуль или в библиотеку. Указанный файл должен быть файлом ресурсов Windows. По умолчанию расширение файлов ресурсов — .RES.
В процессе компоновки компилированной программы или библиотеки файлы, указанные в директивах <$R>, копируются в выполняемый модуль. Компоновщик Delphi ищет эти файлы сначала в том каталоге, в котором расположен модуль, содержащий директиву <$R>, а затем в каталогах, указанных при выполнении команды главного меню Project | Options на странице Directories/Conditionals диалогового окна в опции Search path или в опции /R командной строки DCC32.

При генерации кода модуля, содержащего форму, Delphi автоматически включает в файл .pas директиву <$R *.DFM>, обеспечивающую компоновку файлов ресурсов форм. Эту директиву нельзя удалять из текста модуля, так как в противном случае загрузочный модуль не будет создан и генерируется исключение EResNotFound.

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

Читайте также:

  1. Структура компилятора

Деректива

Abstract Определяет метод класса, осуществляемый только в подклассах Default Определяет обработку для property используемую по умолчанию Dynamic Позволяет методу класса быть заменённым в производных классах System Export Делает функцию или процедуру в DLL внешне доступной Index Определяет преимущественно индексированные классы свойств данных Out Идентифицирует стандартный параметр только для вывода Overload Позволяет 2-м или более подпрограммам иметь одинаковое название Override Определяет метод, который заменяет виртуальный родительский метод класса Private Начинает частный (Private) раздел данных и методов в классе Protected Начинает раздел класса частных данных доступных подклассам Public Начинает внешне доступный раздел класса Published Начинается изданный, внешне доступный раздел класса Virtual Позволяет методу класса быть отменённым в производных классах

$A Определяет данные будут выровнены или запакованы $Align Определяет данные будут выровнены или запакованы $AppType Определяет тип приложения: GUI или Console $B Сокращаются ли вычисления при операциях or или and $BoolEval Сокращаются ли вычисления при операциях or или and$D Определяет будет ли формироваться отладочная информация приложения $DebugInfo Определяет будет ли формироваться отладочная информация приложения $Define Определяет символ директивы компилятора, который используется IfDef$DefinitionInfo Определяет, формируется ли информация символа приложения $Else Начинает дополнительный раздел IfDef или IfNDef$EndIf Заканчивает условную компиляцию кода $ExtendedSyntax Контроль обработки некоторых расширений Паскаля $H Обрабатывает строковые типы, такие как AnsiString или ShortString. $Hints Определяет, показывает ли Delphi подсказки компиляции. $I Позволяет встроить код указанного файла в модуль $IfDef Выполняет код, если условный символ был определен $IfNDef Выполняет код, если условный символ не был определен $IfOpt Проверяет состояние директивы компилятора $Include Позволяет коду в указанном файле быть включенным в Модуль $IOChecks $L Определяет, какое приложение сформировало отладочную информацию $LocalSymbols Определяет, какое приложение сформировало отладочную информацию $LongStrings Обрабатывает тип string такие как AnsiString или ShortString $MinEnumSize Устанавливает минимальную память, используемую для хранения перечислимых типов $O Определяет, оптимизирует ли Delphi код при компиляции $Optimization Определяет, оптимизирует ли Delphi код при компиляции $OverFlowChecks Определяет, проверяет ли Delphi целочисленные и перечислимые границы $R Определяет, проверяет ли Delphi границы массива $RangeChecks Определяет, проверяет ли Delphi границы массива $ReferenceInfo Определяет, будет ли сформирована символьная ссылочная информация $Resource Определяет файл ресурса, который будет включен в приложение $Warnings Определяет, показывает ли Delphi предупреждениям компиляции $X Контроль обработки некоторых расширений Паскаля $Y Определяет, сформирована ли информация, обозначающая приложение $Z Устанавливает минимальную память, необходимую для держания в памяти перечислимых типов If Начинает условное выражение, чтобы решить, что делать далее Implementation Начинает раздел исполняемого кода в модуле

Дата добавления: 2015-06-27 ; Просмотров: 90 ; Нарушение авторских прав? ;

Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет

$BoolEval — Директива компилятора Delphi

<$M>и — директивы, определяющие размер стека

<$M+>и — директивы информации времени выполнения о типах

<$Q+>и — директивы проверки переполнения целочисленных операций

— директива связывания ресурсов

<$R+>и — директивы проверки диапазона

<$APPTYPE CONSOLE> — директива создания консольного приложения

1) Директивы компилятора, разрешающие или запрещающие проверку утверждений.

По умолчанию или

Область действия локальная

Директивы компилятора $C разрешают или запрещают проверку утверждений. Они влияют на работу процедуры Assert,используемой при отладке программ. По умолчанию действует директива и процедура Assert генерирует исключение EAssertionFailed, если проверяемое утверждение ложно.

Так как эти проверки используются только в процессе отладки программы, то перед ее окончательной компиляцией следует указать директиву . При этом работа процедур Assert будет блокировано и генерация исключений EassertionFailed производиться не будет.

Директивы действуют на весь файл исходного кода независимо от того, в каком месте файла они расположены.

2) Директивы компилятора, включающие и выключающие контроль файлового ввода-вывода.

По умолчанию или

Область действия локальная

Директивы компилятора $I включают или выключают автоматический контроль результата вызова процедур ввода-вывода Object Pascal. Если действует директива , то при возвращении процедурой ввода-вывода ненулевого значения генерируется исключение EInOutError и в его свойство errorcode заносится код ошибки. Таким образом, при действующей директиве <$I+>операции ввода-вывода располагаются в блоке try. except, имеющем обработчик исключения EInOutError. Если такого блока нет, то обработка производится методом TApplication.HandleException.

Если действует директива , то исключение не генерируется. В этом случае проверить, была ли ошибка, или ее не было, можно, обратившись к функции IOResult. Эта функция очищает ошибку и возвращает ее код, который затем можно анализировать. Типичное применение директивы и функции IOResult демонстрирует следующий пример:

<$I+>
i:=IOResult;
if i<>0 then
case i of
2: .
3: .
.
end;

В этом примере на время открытия файла отключается проверка ошибок ввода вывода, затем она опять включается, переменной i присваивается значение, возвращаемое функцией IOResult и, если это значение не равно нулю (есть ошибка), то предпринимаются какие-то действия в зависимости от кода ошибки. Подобный стиль программирования был типичен до введения в Object Pascal механизма обработки исключений. Однако сейчас, по-видимому, подобный стиль устарел и применение директив $I потеряло былое значение.

3) Директивы компилятора, определяющие размер стека

По умолчанию <$M 16384,1048576>

Область действия глобальная

Локальные переменные в процедурах и функциях размещаются в стеке приложения. При каждом вызове процедуры или функции ее локальные переменные помещаются в стек. При выходе из процедуры или функции эти локальные процедуры удаляются из стека.

Директивы компилятора $M задают параметры стека приложения: его минимальный и максимальный размеры. Приложение всегда гарантировано имеет размер стека, равный его минимальной величине. Если при запуске приложения Windows обнаруживает, что не может выделить этот минимальный объем памяти, то выдается сообщение об этой ошибке.

Если во время работы выясняется, что минимального размера стека не хватает, то размер увеличивается на 4 K, но не более, чем до установленного директивой максимального размера. Если увеличение размера стека невозможно из-за нехватки памяти или из-за достижения его максимальной величины, генерируется исключение EStackOverflow. Минимальный размер стека по умолчанию равен 16384 (16K). Этот размер может изменяться параметром minstacksize директивы <$M>или параметром number директивы .

Максимальный размер стека по умолчанию равен 1,048,576 (1M). Этот размер может изменяться параметром maxstacksize директивы или параметром number директивы . Значение минимального размера стека может задаваться целым числом в диапазоне между1024 и 2147483647. Значение максимального размера стека должно быть не менее минимального размера и не более 2147483647. Директивы задания размера стека могут включаться только в программу и не должны использоваться в библиотеках и модулях.

В Delphi 1 имеется процедура компилятора , осуществляющая переключение контроля переполнения стека. Теперь этот процесс полностью автоматизирован и директива оставлена только для обратной совместимости.

4) Директивы компилятора, включающие и выключающие генерацию информации времени выполнения о типах (runtime type information — RTTI).

По умолчанию или

Область действия локальная

Директивы компилятора $M включают или выключают генерацию информации времени выполнения о типах (runtime type information — RTTI). Если класс объявляется в состоянии <$M+>или является производным от класса объявленного в этом состоянии, то компилятор генерирует RTTI о его полях, методах и свойствах, объявленных в разделе published. В противном случае раздел published в классе не допускается. Класс TPersistent, являющийся предшественником большинства классов Delphi и все классов компонентов, объявлен в модуле Classes в состоянии . Так что для всех классов, производных от него, заботиться о директиве не приходится.

5) Директивы компилятора, включающие и выключающие проверку переполнения при целочисленных операциях

По умолчанию или

Область действия локальная

Директивы компилятора $Q включают или выключают проверку переполнения при целочисленных операциях. Под переполнением понимается получение результата, который не может сохраняться в регистре компьютера. При включенной директиве проверяется переполнение при целочисленных операциях +, -, *, Abs, Sqr, Succ, Pred, Inc и Dec. После каждой из этих операций размещается код, осуществляющий соответствующую проверку. Если обнаружено переполнение, то генерируется исключение EIntOverflow. Если это исключение не может быть обработано, выполнение программы завершается.

Директивы $Q проверяют только результат арифметических операций. Обычно они используются совместно с директивами , проверяющими диапазон значений при присваивании.

Директива замедляет выполнение программы и увеличивает ее размер. Поэтому обычно она используется только во время отладки программы. Однако, надо отдавать себе отчет, что отключение этой директивы приведет к появлению ошибочных результатов расчета в случаях, если переполнение действительно произойдет во время выполнении программы. Причем сообщений о подобных ошибках не будет.

6) Директивы компилятора, включающие и выключающие проверку диапазона целочисленных значений и индексов

По умолчанию или

Область действия локальная

Директивы компилятора $R включают или выключают проверку диапазона целочисленных значений и индексов. Если включена директива , то все индексы массивов и строк и все присваивания скалярным переменным и переменным с ограниченным диапазоном значений проверяются на соответствие значения допустимому диапазону. Если требования диапазона нарушены или присваиваемое значение слишком велико, генерируется исключение ERangeError. Если оно не может быть перехвачено, выполнение программы завершается.

Проверка диапазона длинных строк типа Long strings не производится.

Директива замедляет работу приложения и увеличивает его размер. Поэтому она обычно используется только во время отладки.

7) Директива компилятора, связывающая с выполняемым модулем файлы ресурсов

Область действия локальная

Директива компилятора указывает файлы ресурсов (.DFM, .RES), которые должны быть включены в выполняемый модуль или в библиотеку. Указанный файл должен быть файлом ресурсов Windows. По умолчанию расширение файлов ресурсов — .RES.

В процессе компоновки компилированной программы или библиотеки файлы, указанные в директивах , копируются в выполняемый модуль. Компоновщик Delphi ищет эти файлы сначала в том каталоге, в котором расположен модуль, содержащий директиву , а затем в каталогах, указанных при выполнении команды главного меню Project | Options на странице Directories/Conditionals диалогового окна в опции Search path или в опции /R командной строки DCC32.

При генерации кода модуля, содержащего форму, Delphi автоматически включает в файл .pas директиву <$R *.DFM>, обеспечивающую компоновку файлов ресурсов форм. Эту директиву нельзя удалять из текста модуля, так как в противном случае загрузочный модуль не будет создан и генерируется исключение EResNotFound.

Директивы компилятора — Версии Delphi

У меня есть блок, который я написал в Delphi 7 некоторое время назад, и просто получил удовольствие (боль) от преобразования в Delphi XE (Unicode).

Устройство работает отлично после некоторых проблем, теперь я пытаюсь сделать этот аппарат совместимым с различными версиями Delphi, если мне когда-либо понадобится переключить IDE обратно в Delphi 7, обновляя какой-либо другой код.

У меня только Delphi 7 и Delphi XE, но из того, что я собираю, код, написанный в Delphi 1, Delphi 2007 будет компилироваться, но код из Delphi 2009 и выше будет Unicode.

. Во всяком случае, в блоке я отделяющий не-Юникод и Юникод, как так:

Как изменить директиву компилятора поэтому правила применяются к Многоязычным версиям? Например, что-то вроде:

Это будет охватывать все версии Delphi, если я буду распространять источник или блок .dcu.

Создан 25 ноя. 11 2011-11-25 14:07:16 Anonymous

2 ответа

Интересно, является ли самый простой подход в этом случае переключать поведение на UNICODE условно. Это условие определено тогда и только тогда, когда вы используете Unicode-версию Delphi, то есть в Delphi 2009 и более поздних версиях. Большим преимуществом этого является то, что это будущее доказательство — вам не нужно обновлять свой код каждый раз, когда выпускается новый Delphi. Более того, условный переключатель будет гораздо читабельнее, поскольку он четко выражает намерение.

Документация Delphi имеет отличный topic, содержащий все предопределенные условные обозначения. Полный список условных обозначений версии также linked оттуда.

Создан 25 ноя. 11 2011-11-25 14:20:45 David Heffernan

+1, вы были быстрее. Если OP хочет только разделить код на Unicode-версию Delphi, то директива ‘UNICODE’ является точной. Существуют также CompilerVersion и RTLVersion для определения текущей версии Delphi. – TLama 25 ноя. 11 2011-11-25 14:31:10

. если кто-то использовал «UNICODE» в прошлом. Например, чтобы удовлетворить отсутствие поддержки Unicode в самой Delphi;) . все еще, +1 . ваше решение кажется более чистым, если можно гарантировать, что ‘UNICODE’ еще не используется. – 0xC0000022L 25 ноя. 11 2011-11-25 14:33:44

@STATUS_ACCESS_DENIED В этом случае необходимо изменить код, который определяет и использует пользовательский условный символ с именем UNICODE. – David Heffernan 25 ноя. 11 2011-11-25 14:36:29

@ Давид: Я не уверен, что согласен. В C/C++ для определенных объектов (определений и функций) было принято, чтобы они начинались с двух ведущих подчеркиваний, если они специфичны для компилятора. Borland (et al.) Должен был бы сделать такие правила давно. Они меняют правила и постоянно нарушают код. В частности, поддержка Unicode/была бесполезной в этом отношении. Я до сих пор не понимаю, как совершенные дельфийцы могут оставаться такими спокойными;) . Я некоторое время оставил все это позади меня, хотя по-прежнему пользуюсь Delphi. – 0xC0000022L 25 ноя. 11 2011-11-25 14:53:46

@STATUS Как бы то ни было, это то, что есть, и если Emba определит ‘UNICODE’, тогда вам не нужно, нравится вам это или нет. – David Heffernan 25 ноя. 11 2011-11-25 14:54:52

@ Давид спасибо за информацию, используя директиву UNICODE намного лучше :)user741875 25 ноя. 11 2011-11-25 15:09:07

Ваш лучший выбор — это посмотреть на один из многих проектов JEDI, например, http://sourceforge.net/projects/jedi-apilib/ и посмотреть, как они это делают. У них есть общие файлы, содержащие именно те детали, которые вас интересуют. JVCL — еще один хороший выбор .

Создан 25 ноя. 11 2011-11-25 14:11:10 0xC0000022L

Да jvcl inc совершенен. Существует только каждая директива компилятора для кодирования некоторых разделов, относящихся к конкретным версиям. – az01 25 ноя. 11 2011-11-25 14:18:50

Илон Маск рекомендует:  Что такое код asp logextfileflags
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL