Delphi: Все константы являются постоянными, но некоторые являются более постоянными, чем другие?

Рассмотрите:

const 
   clHotlight: TColor = $00FF9933;
   clLink = clHotLight; //alias of clHotlight

[Error] file.pas: Constant expression expected

и альтернатива, формулирующая, который работает:

const 
   clHotlight = TColor($00FF9933);
   clLink = clHotLight; //alias of clHotlight

Объяснить.


Затем рассмотрите:

const 
   AdministratorGUID: TGUID = '{DE44EEA0-6712-11D4-ADD4-0006295717DA}';
   SuperuserGUID = AdministratorGUID; //alias of AdministratorGUID

[Error] file.pas: Constant expression expected

И зафиксируйте.

Править: Добавленное ключевое слово const перед объявлениями; кто-то не полагал, что они были константой.

22
задан Ian Boyd 26 April 2010 в 20:59
поделиться

7 ответов

clHotlight: TColor = $ 00FF9933; не константа, но типизированная константа (= статическая переменная), то есть компилятор резервирует слот в памяти для TColor, который будет содержать значение $ 00FF9933 первоначально во время выполнения.
Поскольку это значение можно изменить позже (с включенной опцией Assignable Const), оно не является реальной константой и не может быть принято компилятором в clLink = clHotLight;

clHotlight = TColor ($ 00FF9933); строго совпадает с clHotlight = $ 00FF9933;
Это истинная константа, и компилятор заменит clHotlight на его значение $ 00FF9933 в любом месте кода. А также для clLink .

Прочтите этот вопрос SO ( В Delphi 7, почему я могу присвоить значение константе? ) и все хорошие ответы там ...

РЕДАКТИРОВАТЬ: о TGUID ...
Проблема в том, что запись AdministratorGUID: TGUID = '{DE44EEA0-6712-11D4-ADD4-0006295717DA}'; некорректна.
Он использует некоторую магию компилятора для вызова StringToGUID за кулисами, что позволяет удобно выразить GUID в виде строки, которой они не являются по своей природе. Это записи.

Итак, попытка AdministratorGUID = '{DE44EEA0-6712-11D4-ADD4-0006295717DA}'; не сработает. Это не GUID ...

Временное решение - иметь типизированную константу и переменные , указывающие на одну и ту же область памяти, с помощью директивы absolute :

const
   AdministratorGUID: TGUID = '{DE44EEA0-6712-11D4-ADD4-0006295717DA}';
var
   SuperuserGUID: TGUID absolute AdministratorGUID; //alias of AdministratorGUID
   RootGUID: TGUID absolute AdministratorGUID;      //alias of AdministratorGUID
23
ответ дан 29 November 2019 в 04:29
поделиться

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

Чего еще не было показано, так это того, как обойти проблему (в большом количестве случаев), хотя пара очень близко подошла к тому, чтобы раскрыть этот секрет ... :)

В вашем конкретном случае вы можете обойти проблему, изменив "псевдоним" значения и объявления типизированной константы следующим образом:

const
  clLink = $00FF9933;
  clHotlight: TColor = clLink;

clLink теперь предоставляет вашу истинную константу, а clHotlight - это типизированная константа, которая имеет то же значение, что и clLink .

Для идентификатора GUID можно использовать тот же метод, но вы должны иметь в виду обычное постоянное выражение, используемое для инициализации типизированной константы GUID - оно использует не запись, а простую буквальную строку, поэтому:

const
  ID_CONSTANT = '{AA1C8AF2-C290-40AB-9CF5-2888A46E1660}';
  GUID_CONSTANT: TGUID = ID_CONSTANT;

ПРИМЕЧАНИЕ. Такие константы GUID можно использовать везде, где требуются TGUID , например IsEqualGUID (tguid, GUID_CONSTANT) и т. Д.

4
ответ дан 29 November 2019 в 04:29
поделиться
3
ответ дан 29 November 2019 в 04:29
поделиться

Я пробовал этот код:

  const
    CAnswer1 = 42;
    CAnswer2 : Integer = 42;

  var
    LAnswer : Integer;

  begin
    LAnswer := CAnswer1;
    LAnswer := CAnswer2;
  end;

и вот полученный код:

Project9.dpr.18: LAnswer := CAnswer1;
004101AC C7056C6E41002A00 mov [$00416e6c],$0000002a //<- assign a hard-coded "42" value
Project9.dpr.19: LAnswer := CAnswer2;
004101B6 A1701C4100       mov eax,[$00411c70] //<- fetch a variable's content
004101BB A36C6E4100       mov [$00416e6c],eax //<- assign this content 

Вы правы: некоторые константы более постоянны, чем другие. {{ 1}} Вторая константа фактически обрабатывается компилятором как переменная.

7
ответ дан 29 November 2019 в 04:29
поделиться

добро пожаловать в Delphi evolution. в delphi 1 и 2 вы не можете присвоить начальное постоянное значение глобальной переменной (например: var xVar: Integer = 1). Единственный способ сделать это - использовать const xVar: Integer = 1) и некоторые из ваших кодов, затем вы можете изменить его на что-то другое, если хотите. Пока они не избавятся от этой древней функции, вы не можете использовать конструкцию const xVar: Integer в качестве значения const.

Ура A Pham

1
ответ дан 29 November 2019 в 04:29
поделиться

Правая часть объявления константы должно быть «постоянным выражением», которое определяется как «постоянное выражение - это выражение, которое компилятор может вычислить, не выполняя программу, в которой оно встречается». Вы можете найти весь принятый синтаксис для константного выражения в руководстве по языку. Обратите внимание, что в руководстве по языку явно указано: «Типизированные константы не могут встречаться в постоянных выражениях». - и поэтому ваши объявления не работают, clHotlight: TColor = $ 00FF9933; и AdministratorGUID: TGUID = ...; являются типизированными константами. Кроме того, постоянное выражение не может включать в себя вызовы функций, кроме перечисленных в руководстве по языку (например, Length (), SizeOf () и некоторых других), которые компилятор может вычислить во время компиляции. { {1}} Перепишите так:

const
  AdminGUID = '{DE44EEA0-6712-11D4-ADD4-0006295717DA}';
  AdministratorGUID: TGUID = AdminGUID;
  SuperuserGUID: TGUID = AdminGUID;

И это сработает.

2
ответ дан 29 November 2019 в 04:29
поделиться
clHotlight: TColor = $00FF9933; 
          ^

объявляет clHotlight как « переменную » (ну, хорошо, «присваиваемая константа», если вы разрешено это в параметрах компилятора) с помощью : .

Как вы обнаружили, объявление:

clHotlight = TColor($00FF9933); 

не выделяет clHotlight , пока это не будет указано позже.

То же самое относится и к вашему GUID.

5
ответ дан 29 November 2019 в 04:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: