Директивы в Delphi

Содержание

Директива Delphi $ Message на основе условия

Я хочу генерировать фатальную ошибку компилятора, используя директиву <$Message Fatal ''>, но основанную на значении поля. Например:

Но это не работает.

Я сделал ошибку в коде? Или есть лучший способ использовать условную директиву сообщений?

Вы не можете использовать Pascal, if компилятор все еще компилирует все ветки. Вместо этого вы должны использовать условную директиву, такую как <$IF>.

Конечно, это означает, что условие оценивается компилятором, а не во время выполнения. Но это вряд ли удивительно, если вы хотите сгенерировать ошибку времени компиляции.

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

Поле, которое вы тестируете, может быть изменено во время выполнения.

Сообщения компилятора генерируются во время компиляции. Невозможно создать сообщение об ошибке времени компиляции на основе условий времени выполнения.

У вас есть два варианта:

Используйте ASSERT() чтобы проверить значение поля во время выполнения и вызвать исключение, если обнаружено, что это условие было нарушено.

Замените поле символом, который можно установить и протестировать с помощью директив компилятора.

Из этих двух я сильно подозреваю, что утверждение является наиболее подходящим подходом в вашем случае, но для полноты здесь есть два подхода и различия между ними.

Подход ASSERT

И ваш оператор if и необходимость вызова EXIT объединяются в один вызов ASSERT() :

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

В противном случае ошибка утверждения предупреждает разработчика (или если вы небрежны, пользователь) к ошибке.

Подход символов компилятора

Либо используя параметр проекта, либо некоторую условную компиляцию в вашем устройстве или подходящий файл include, определите символ FILELISTMODE .

Затем ваш оператор if заменяется тестом на определение этого символа, но по-прежнему нет необходимости вызывать EXIT поскольку компиляция просто не срабатывает немедленно, если символ не определен:

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

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

Директивы в Delphi

3437 просмотра

3 ответа

2628 Репутация автора

я работаю над приложением с использованием Delphi 7 , и я только что наткнулся на это

автор кода поместил так много директив компилятора перед именем основного модуля.

может кто-нибудь сказать мне

  1. Какая польза от наличия Директив перед именем единицы, это делает их глобальными?
  2. И можем ли мы создавать свои собственные директивы в некоторых конкретных ситуациях?
  3. где определены директивы компилятора?

Автор: PresleyDiasИсточник Размещён: 17.01.2012 11:10

Ответы (3)

7 плюса

527596 Репутация автора

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

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

Директивы Switch являются глобальными или локальными:

  • Глобальные директивы влияют на всю компиляцию и должны появляться перед частью объявления программы или компилируемого модуля.
  • Локальные директивы влияют только на ту часть компиляции, которая простирается от директивы до следующего появления той же директивы. Они могут появиться где угодно.

Однако рассмотрим DENYPACKAGEUNIT директиву (выделено мной):

<$DENYPACKAGEUNIT ON>Директива запрещает Delphi блок , в котором он появляется из помещаются в пакет.

Если эта директива имеет охват всей единицы, то она просто должна присутствовать в единице для вступления в силу.

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

Обратите внимание, что вам нужно устанавливать директивы в коде, только если вы хотите изменить настройки, сделанные в настройках проекта. Вполне разумно устанавливать параметры в настройках проекта, а не устанавливать их в коде.

Похоже, что произошло в коде, который вы представляете, это то, что автор набрал, CTRL+O O и среда IDE вставила различные параметры, определенные в параметрах проекта в тот момент времени.

4 плюса

24047 Репутация автора

  1. Какая польза от наличия Директив перед именем единицы, это делает их глобальными?

Если под глобальным вы подразумеваете весь проект, ответ НЕТ. Каждый модуль компилируется самостоятельно.

  1. И можем ли мы создавать свои собственные директивы в некоторых конкретных ситуациях?

Они называются директивами компилятора, потому что компилятор их интерпретирует. Вы не можете создавать свои собственные директивы, если вы не в Embarcadero и не изменили компилятор.

Они определены в источниках компилятора. Они задокументированы в документации компилятора, и вы уже нашли отличную ссылку (ваша вторая ссылка)

плюса

1 Репутация автора

Спасибо, ребята, за совет CTRL OO, потому что я не знаю, что случилось с моим кодом, когда появились эти стандартные и определенные директивы.

mirsovetov.net

Андрощук Александр, ИТ решения, советы, заметки…

Delphi — <$IFDEF>более одной директивы

Задача: Каким образом можно определить более одного условного оператора в одной проверке <$IFDEF>?
Инструментарий: Delphi
Решение:
Для того чтобы выполнить проверку нескольких условных операторов в одной проверке <$IFDEF>— нужно воспользоваться директивой .

Пример использования:

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

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

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

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

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

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

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

Это позволило бы охватить все версии Delphi я должен распространять исходный или .dcu блок.

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

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

Как задать директивы компилятору для группы проектов в Delphi 7?

Допустим у нас есть 2 группы проектов — ProjectGroupA.bpg и ProjectGroupB.bpg . Каждая группа состоит из EXE и проектов модулей bpl.

В состав каждой группы входят одинаковые проекты Project1.bpl , Project2.bpl , Project3.bpl и разные проекты appA.exe , Project5.bpl и appB.exe , Project6.bpl , примерно вот так: ProjectGroupA.bpg (проекты exeA-1-2-3-5) и ProjectGroupB.bpg (проекты exeB-1-2-3-6).

В общих проектах (1,2,3) есть незначительные отличия для работы в составе приложения A или B, такие, которые хорошо разруливаются директивами условной компиляции (включение некоторых строк в bpl, например).

Вопрос — Как установить директивы компиляции на уровне группы проектов, чтобы при сборке группы проектов A, ко всем модулям применялась директива DEFINE_PROJECT_A , а при сборке группы проектов B, ко всем модулям применялась директива DEFINE_PROJECT_B ?

Использование процедур и функций в Delphi

Скобки

Добавление скобок при вызове процедур и функций без параметров уже давно не является новинкой в Delphi, тем не менее, эта возможность мало известна. Эту возможность оценят по достоинству те программисты, которым приходится работать на двух языках (C++ и Delphi), так как им не нужно будет постоянно помнить о разнице в синтаксисе при вызове процедур и функций в разных языках. В Delphi оба варианта, приведенные ниже, считаются корректными.

Возможность перегрузки

Впервые концепция перегрузки процедур и функций была реализована в Delphi 4. Она позволяет иметь несколько различных процедур и функций с одинаковыми именами, но с разными списками параметров. Такие процедуры и функции должны быть описаны с применением директивы overload.

procedure Test (I: integer); overload;
procedure Test (S: string); overload;
procedure Test (D: double); overload;

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

Передача параметров

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

Передача параметров по значению

Этот режим передачи параметров применяется по умолчанию. Если параметр передается по значению, создается локальная копия данной переменной, которая и предоставляется для обработки в процедуру или функцию. Посмотрите на следующий пример:

procedure Test(s: string);

При вызове указанной процедуры будет создана копия передаваемой ей в качестве параметра строки s, с которой и будет работать процедура Test. При этом все внесенные в строку изменения никак не отразятся на исходной переменной s.

Однако это не относится к объектам. Например, если в функцию передается переменная (а точнее экземпляр объекта) TStringList, то в данном случае произойдет передача по ссылке (даже если это не указано явно). Этот способ передачи является у большинства самым излюбленным, но в тоже время является и самым не практичным, т.к. для выполнения метода выделяется дополнительная память для создания точной копией передаваемой переменой. Для решения этой проблемы следует использовать один из способов описанных ниже.

Передача параметров по ссылке

Pascal позволяет также передавать параметры в функции или процедуры по ссылке — такие параметры называются параметрами-переменными. Передача параметра по ссылке означает, что функция или процедура сможет изменить полученные значения параметров. Для передачи параметров по ссылке используется ключевое слово var, помещаемое в список параметров вызываемой процедуры или функции.

procedure ChangeMe(var x: longint);
begin
x := 2; // Параметр х изменен вызванной процедурой
end;

Вместо создания копии переменной x, ключевое слово var требует передачи адреса самой переменной x, что позволяет процедуре непосредственно изменять ее значение.

Передача параметров констант

Если нет необходимости изменять передаваемые функции или процедуре данные, можно описать параметр как константу. Ключевое слово const не только защищает параметр от изменения, но и позволяет компилятору сгенерировать более оптимальный код передачи строк и записей. Вот пример объявления параметра-константы:

procedure Test(const s: string );

Передача открытых массивов

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

function AddEmUp(A: array of integer): integer;

В открытом массиве можно передавать переменные, константы или выражения из констант.

Для получения информации о фактически передаваемом массиве параметров в функции или процедуре могут использоваться функции High, Low и SizeOf.

Object Pascal также поддерживает тип array of const, который позволяет передавать в одном массиве данные различных типов. Синтаксис объявления функций или процедур, использующих такой массив для получения параметров, следующий:

procedure WhatHaveIGot( A: array of const );

Вызвать объявленную выше функцию можно, например, с помощью такого оператора:

procedure WhatHaveIGot( [‘Text’, 10, 5.5, @WhatHaveIGot, 3.14, true, ‘c’] );

При передаче функции или процедуре массива констант все передаваемые параметры компилятор неявно конвертирует в тип TVarRec. Тип данных TVarRec объявлен в модуле System следующим образом:

PVarRec = ^TVarRec;
TVarRec = record
case Byte of
vtInteger: (VInteger: Integer; VType: Byte);
vtBoolean: (VBoolean: Boolean);
vtChar: (VChar: Char);
vtExtended: (VExtended: PExtended);
vtString: (VString: PShortString);
vtPointer: (VPointer: Pointer);
vtPChar: (VPChar: PChar);
vtObject: (VObject: TObject);
vtClass: (VClass: TClass);
vtWideChar: (VWideChar: WideChar);
vtPWideChar: (VPWideChar: PWideChar);
vtAnsiString: (VAnsiString: Pointer);
vtCurrency: (VCurrency: PCurrency);
vtVariant: (VVariant: PVariant);
vtInterface: (VInterface: Pointer);
vtWideString: (VWideString: Pointer);
vtInt64: (VInt64: PInt64);
end;

Поле VType определяет тип содержащихся в данном экземпляре записи TVarRec данных и может принимать одно приведенных значений.

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

procedure WhatHaveIGot( A: array of const );
var
i: integer;
TypeStr: string;
begin
for i := Low(A) to High(A) do
begin
case A[i].VType of
vtInteger : TypeStr := ‘Integer’;
vtBoolean : TypeStr := ‘Boolean’;
vtChar : TypeStr := ‘Char’;
vtExtended : TypeStr := ‘Extended’;
vtString : TypeStr := ‘String’;
vtPointer : TypeStr := ‘Pointer’;
vtPChar : TypeStr := ‘PChar’;
vtObject : TypeStr := ‘Object’;
vt ;
vtW ;
vtPW ;
vtAnsiString : TypeStr := ‘AnsiString’;
vtCurrency : TypeStr := ‘Currency’;
vtVariant : TypeStr := ‘Variant’;
vtInterface : TypeStr := ‘Interface’;
vtW ;
vtInt64 : TypeStr := ‘Int64’;
end;
ShowMessage( Format( ‘Array item %d is a %s’, [i, TypeStr] ) );
end;
end;

Значения параметров по умолчанию

В Delphi есть одна очень полезная возможность — использование значений параметров по умолчанию. Она позволяет установить принимаемое по умолчанию значение параметра процедуры или функции. Это значение будет использоваться в тех случаях, когда вызов процедуры или функции производится без указания значения данного параметра. В объявлении процедуры или функции принимаемое по умолчанию значение параметра указывается после знака равенства, следующего после его имени. Поясним это на следующем примере:

procedure HasDefVal( s: string; i: integer = 0 );

Подобное объявление означает, что процедура HasDefVal может быть вызвана двумя путями. В первом случае — как обычно, с указанием обоих параметров:

procedure HasDefVal( ‘Hello’, 26 );

Во втором случае можно задать только значение параметра s, а для параметра i использовать значение, установленное по умолчанию:

procedure HasDefVal( ‘Hello’ );

При использовании значении параметров по умолчанию следует помнить о нескольких приведенных ниже правилах:

  • Параметры, имеющие значения по умолчанию, должны располагаться в конце списка параметров. Параметр без значения по умолчанию не должен встречаться в списке после параметра, имеющего значение по умолчанию.
  • Значения по умолчанию могут присваиваться только параметрам обычных типов, указателям или множествам.
  • Значение по умолчанию может передаваться только по значению либо с модификатором const. Оно не может быть ссылкой или нетипизированным параметром.

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

function Add( I1, I2: integer ): integer;
begin
Result := I1 + I2;
end;

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

function Add( I1, I2: integer; I3: integer = 0 ): integer;
begin
Result := I1 + I2 + I3;
end;

Директива

Директива <$X->запрещает вызов функций как процедур (с игнорированием возвращаемого результата). По умолчанию этот режим включен (<$X+>). Так вот, запомните, использование переменной Result недопустимо при сброшенном флажке опции Extended Syntax, расположенном во вкладке Compiler диалогового окна Project Options, или при указании директивы компилятора <$X->.

В каждой функции языка Objecl Pascal существует локальная переменная с именем Result, предназначенная для размещения возвращаемого значения. Кроме того, вернуть значение из функции можно также путем присвоения значения переменной, имеющей то же имя, что и данная функция. Это стандартный синтаксис языка Pascal, сохранившийся от его предыдущих версий. При использовании в теле функции переменной с ее именем не забывайте, что существуют большие отличия в обработке этого имени — все зависит от того, где она расположена — в левой части оператора присвоения или же в любом другом месте текста функции. Если имя функции указано в левой части оператора присвоения, то предполагается, что назначается возвращаемое функцией значение. Во всех других случаях предполагается, что осуществляется рекурсивный вызов этой функции.

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

Режимы компиляции

18.04.2005
Иван Шихалев

Режимы компиляции, или иначе — режимы совместимости, в Free Pascal определяют, каким диалектом языка Pascal вы хотите вос­поль­зо­вать­ся. Режим определяет возможные конструкции языка, некоторые типы данных и системные модули подгружаемые по умол­ча­нию.

Режим компиляции выставляется при помощи ключа командной строки -S или непосредственно в модуле при помощи директивы <$MODE xxx>.

В этом же обзоре я намерен описать прочие ключи компилятора, определяющие расширения языка.

Режим по умолчанию. Соответственно в ключах командной строки своего символа не имеет. Что, впрочем, не есть хорошо, по­сколь­ку существует же еще и файл ppc386.cfg — его установки таким образом мы можем сменить на FPC только через директиву.

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

. Что са­мое интересное — это распространяется и на функции. Выражение @

однозначно трактуется как адрес переменной, а не процедуры, на которую она ссылается. Кстати, в справке по этому поводу ошибка, или я что-то не так понял: «You must use the address operator to assign procedural variables.»

Заголовок предварительно объявленной (в интерфейсной части модуля или при помощи директивы forward ) функции или про­це­ду­ры должен полностью совпадать с ее заголовком при реализации. То есть опускать список аргументов и тип результата — не­ль­зя.

Разрешена перегрузка (overloading) процедур и функций. Кстати, в отличие от Delphi, директиву overload использовать не­обя­за­тель­но.

Разрешены вложенные комментарии, таким образом, конструкция < comment < nested comment >> не вызовет ошибки ком­пи­ля­то­ра.

Не поддерживаются классы. Из-за того, что обработка исключений реализована a-la Delphi, не поддерживается оператор try .

Не подгружается модуль ObjPas . Что это за зверь, я слегка опишу, когда перейдем к <$MODE OBJFPC>, пока лишь замечу, что тип integer без ObjPas соответствует 2м байтам, а с ним — 4м.

Не поддерживается ключевое слово resourcestring .

До кучи ко всем огорчениям, не поддерживается псевдо(?)переменная result — результат функции присваивается ее имени.

Зато поддерживается директива cvar и внешние переменные.

Автоматически производится присваивание PChar -> string .

Поддерживается такая замечательная вещь, как перегрузка операторов.

Режим совместимости с Turbo Pascal фирмы Borland версии 7. Соответствует ключу командной строки -So .

Совместимость обеспечивается полная — единственное различие в том, что исполняемый файл 32-разрядный, других Free Pascal не создает.

Писать программы непосредственно в этом режиме, на мой взгляд — мазохизм. А вот портировать старые программы для TP легко — как правило, не требуется вносить каких-либо изменений в код.

В силу полной совместимости, воздержусь от подробного описания этого режима — чего-чего, а уж литературы по Turbo Pascal до­ста­точ­но, и в Сети, и в книжных магазинах.

По идее — режим совместимости с GPC — GNU Pascal. Ключ командной строки — -Sp .

Судя по всему — разработка данного режима для команды FPC — мягко говоря, задача не приоритетная. Реально никаких свой­ствен­ных GPC расширений не поддерживается, и от <$MODE TP>этот режим отличается только использованием адресного опе­ра­то­ра для процедурных переменных.

Это — режим Object Pascal. Соответствует ключу командной строки -S2 .

Работа с процедурными переменными полностью аналогична режиму <$MODE FPC>. Аналогично с заголовками функций и про­це­дур — они должны повторяться в точности при реализации. Вообще, режимы очень похожи, главное отличие — поддержка клас­сов.

Классы почти полностью идентичны классам в Delphi. Естественно, published практически эквивалентно public . Кроме того, пе­ре­груз­ка методов не требует директивы overload . Обидно, что не поддерживаются интерфейсы, но авторы обещают сделать это к версии 1.2.

Автоматически подгружается модуль ObjPas . Данный модуль по сути дополняет функциональность модуля System с уровня Turbo Pascal до уровня Delphi. Хотя, конечно, это грубое упрощение. Что реально он делает?

  • Во-первых, определяет тип smallint — целое со знаком длиной в слово, и переопределяет тип integer — в отличие от других режимов он означает целое со знаком размером в двойное слово, что соответствует типу longint , который остается таким же.
  • Во-вторых, для совместимости с Delphi определены процедуры AssignFile и CloseFile .
  • В-третих, переопределяет процедуры GetMem и FreeMem . К сожалению, я пока не ковырялся в исходниках и не могу сказать, что именно в их реализации изменено.
  • И в-четвертых, в этом модуле определяются функции для работы с ресурсными строками.

Free Pascal при <$MODE OBJFPC>поддерживает работу с ресурсными строками, через resourcestring .

При написании функций, для возвращаемого значения можно использовать псевдопеременную result . Что на мой взгляд гораздо удоб­нее, чем имя функции, особенно при итерациях.

Преобразование PChar -> string производится при присваивании автоматически.

Второе (после классов) по важности преимущество данного режима — обработка исключений в блоках try . except . end и try . finally . end . Данный механизм Free Pascal поддерживает полностью аналогично Delphi — то есть вы можете пе­ре­хва­ты­вать исключения, обрабатывать в зависимости от класса с помощью ключевого слова on , определять собственные классы ис­клю­че­ний и вызывать их (или стандартные) посредством оператора raise . Для корректной работы с исключениями нужно под­клю­чать, как и в Delphi, модуль SysUtils , который содержит базовый класс Exception и стандартные классы исключений.

В общем и целом данный режим очень похож на Object Pascal a-la Borland Delphi. Разработчики намерены реализовать и ин­тер­фей­сы к версии 1.2, но когда она выйдет, пока неизвестно.

Режим совместимости с Borland Delphi версии 2, если я не ошибаюсь. Соответствует ключу командной строки -Sd .

От <$MODE OBJFPC>отличается весьма незначительно:

  • Во-первых, необязательно в секции implementation повторять заголовок процедуры или функции.
  • И, во-вторых, не разрешена перегрузка функций, процедур и операторов.

В целом, я бы рекомендовал все-таки <$MODE OBJFPC>, который соединяет в себе объектную модель Object Pascal со всеми пре­лес­тя­ми собственно FPC.

Прочие расширения языка

Поддержка inline- процедур, функций и операторов. Определяется директивой компилятора <$INLINE ON/OFF>и ключом ко­манд­ной строки -Si . Inline-процедуры описываются директивой inline в заголовке, могут быть как нормальными пас­ка­лев­ски­ми, так и ассемблерными (при использовании директивы assembler ), то есть не требуют знания машинных кодов, как директива inline в Turbo Pascal. При использовании этой возможности следует помнить, что в случае ошибки (рекурсия, etc.) компилятор по­че­му-то не выдает осмысленного сообщения, а слетает на «Internal Error». Если inline-процедура используется за пределами про­грамм­но­го модуля, где она непосредственно описана, то трактуется как обычная вызываемая процедура.

Поддержка простых макросов. Определяется директивой компилятора <$MACRO ON/OFF>и ключом командной строки -Sm . Са­ми макросы определяются так <$DEFINE MACRO_NAME := EXPRESSION>, где MACRO_NAME — идентификатор, который в даль­ней­шем тексте программы будет заменяться на выражение EXPRESSION .

Поддержка специальных операторов присваивания в стиле Си. Определяется ключом командной строки -Sc , собственной ди­рек­ти­вы компилятора не имеет. Разрешает присваивание с одновременным сложением, вычитанием, умножением или делением, ис­поль­зуя операторы += , -= , *= и /= соответственно.

$Align — директива компилятора

Posted by key under Delphi

Определяет, были ли данные выровнены или упакованы

Описание:

С $Align On (по умолчанию), сложные типы данных, такие как записи, хранят свои элементы, выровненные по 2, 4 или 8-байтовой границе, соответственно типу данных. Например, поле типа Word будет выровнено по 4-байтовой границе.

С $Align On, значением по умолчанию, вы можете перекрыть эти настройки с помощью опции packed для сложных типов данных.

Выравнивание обеспечивает оптимальную скорость доступа.

$Align Off указывает Delphi игнорировать выравнивание, и таким образом пакует данные.

Пример кода:

// Declare a packed record
TPackedRecord = Packed Record
name1 : string[4];
floater : single;
name2 : char;
int : Integer;
end;

// Set alignment off

// Declare an unpacked record
// This will get treated as if packed was on
TUnPackedRecord = Record
name1 : string[4];
floater : single;
name2 : char;
int : Integer;
end;

var
alignedRec : TAlignedRecord;
packedRec : TPackedRecord;
unPackedRec : TUnPackedRecord;

begin
ShowMessage(‘Aligned record size = ‘+IntToStr(SizeOf(alignedRec)));
ShowMessage(‘Packed record size = ‘+IntToStr(SizeOf(packedRec)));
ShowMessage(‘UnPacked record size = ‘+IntToStr(SizeOf(unPackedRec)));
end;

Директивы Компилятора-Версии 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 документация имеет отличный темы список всех предопределенных условий. Полный список условий версии также связан оттуда.

Вопрос по angularjs-scope, angularjs &#8211 Значение $ rootscope, используемое в контроллере, переопределяется при обновлении страницы, используемой этим контроллером

На моей странице angularjs я передаю глобальные данные другому контроллеру, используя объект $ rootscope angularjs. В моем контроллере я успешно могу поймать значение, хранящееся в объекте $ rootscope, и значение заполняется правильно, и я использую значение в элементе управления меткой. Но когда я обновляю страницу, значение исчезает. В чем проблема в этом и как я могу преодолеть эту ситуацию.

Спасибо и всего наилучшего Утпал

вся информация, хранящаяся в переменных JavaScript, будет потеряна. $ rootScope — это не более чем переменная в JavaScript. Если вы хотите сохранить что-то, что сохраняет перезагрузку страницы, есть как минимум следующие возможности:

использовать куки (в угловом вы можете использовать $ cookieStore)использовать некоторые новые функции HTML5, такие как хранилище локали, веб-база данных или старое хранилище DOM (http://en.wikipedia.org/wiki/Web_storage)хранить ваши данные на сервере

AngularJS не будет сохраняться между полной перезагрузкой страницы, вы должны использовать другой механизм для сохранения данных между двумя разными загрузками, например, HTML5 localStorage или Cookies и т. Д. Причина, по которой обновление браузера удаляет ваши данные, заключается в том, что все приложение AngularJS разрывается и перезагрузил, так что можетНе ожидайте, что это сохранит состояние.

Если вы хотите сохранить данные между контроллерами, $ rootScope isn ‘это лучший способ. Вы должны посмотреть на angularJSСервисы и использовать их для связи между контроллерами.

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