estatico - Delphi: todas las constantes son constantes, ¿pero algunas son más constantes que otras?
delphi arreglos (7)
Considerar:
const
clHotlight: TColor = $00FF9933;
clLink = clHotLight; //alias of clHotlight
[Error] file.pas: Constant expression expected
y la redacción alternativa que funciona:
const
clHotlight = TColor($00FF9933);
clLink = clHotLight; //alias of clHotlight
Explique.
Entonces considera:
const
AdministratorGUID: TGUID = ''{DE44EEA0-6712-11D4-ADD4-0006295717DA}'';
SuperuserGUID = AdministratorGUID; //alias of AdministratorGUID
[Error] file.pas: Constant expression expected
Y arregla.
Editar: se agregó const
palabras clave antes de las declaraciones; alguien no creía que fueran const.
El lado derecho de una declaración constante debe ser una "expresión constante", que se define como "una expresión constante es una expresión que el compilador puede evaluar sin ejecutar el programa en el que ocurre". Puede encontrar toda la sintaxis aceptada para la expresión constante en la guía de idiomas. Tenga en cuenta que la guía de idiomas establece explícitamente que "las constantes tipadas no pueden aparecer en expresiones constantes". - y es por eso que sus declaraciones fallan, tanto clHotlight: TColor = $ 00FF9933; y AdministratorGUID: TGUID = ...; son constantes tipadas. Además, la expresión constante no puede incluir llamadas a funciones, excepto las enumeradas en la guía de idioma (es decir, Length (), SizeOf () y algunas otras) que el compilador puede calcular en tiempo de compilación. Reescribe de esta manera:
const
AdminGUID = ''{DE44EEA0-6712-11D4-ADD4-0006295717DA}'';
AdministratorGUID: TGUID = AdminGUID;
SuperuserGUID: TGUID = AdminGUID;
Y funcionará.
El problema surge porque una constante tipada no es, en verdad, una constante, como se ha explicado con diversos grados de claridad y éxito por otros.
Lo que aún no se ha demostrado es cómo evitar el problema (en una gran cantidad de casos), aunque una pareja se acercó tentadoramente a renunciar a ese secreto ... :)
En su caso específico, puede evitar el problema invirtiendo el "aliasing" del valor y la declaración de constante tipada de la siguiente manera:
const
clLink = $00FF9933;
clHotlight: TColor = clLink;
clLink ahora proporciona su constante verdadera y clHotlight es la constante tipada que tiene el mismo valor que clLink .
Para los GUID se puede usar la misma técnica, pero hay que tener en cuenta la expresión constante normal utilizada para inicializar una constante GUID tipada: no utiliza un registro sino una cadena literal simple, por lo que:
const
ID_CONSTANT = ''{AA1C8AF2-C290-40AB-9CF5-2888A46E1660}'';
GUID_CONSTANT: TGUID = ID_CONSTANT;
NOTA: Estas constantes de GUID son perfectamente utilizables en todos los lugares donde se requieren los TGUID , por ejemplo, IsEqualGUID (tguid, GUID_CONSTANT), etc.
Intenté este código:
const
CAnswer1 = 42;
CAnswer2 : Integer = 42;
var
LAnswer : Integer;
begin
LAnswer := CAnswer1;
LAnswer := CAnswer2;
end;
y aquí está el código producido:
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
Tienes razón: algunas constantes son más constantes que otras. La segunda constante es realmente tratada por el compilador como una variable.
bienvenido a Delphi evolution. en Delphi 1 y 2, no puede asignar un valor de constante inicial a una var global (por ejemplo: var xVar: Integer = 1). La única forma en que puede hacer eso es usar const xVar: Integer = 1) y en algunos lugares en sus códigos, puede cambiarlo a algo si lo desea. Hasta que se deshagan de esta característica antigua, no se puede usar la construcción "const xVar: Integer" como un valor constante.
Cheers A Pham
clHotlight: TColor = $00FF9933;
no es una constante sino una constante tipada (= variable estática), es decir, el compilador reserva un espacio en la memoria para un TColor que contendrá el valor $00FF9933
inicialmente en tiempo de ejecución.
Debido a que ese valor se puede cambiar más adelante (con la opción Const asignable en ON), no es una constante real y no puede ser aceptado por el compilador en clLink = clHotLight;
clHotlight = TColor($00FF9933);
es estrictamente lo mismo que clHotlight = $00FF9933;
Es una constante verdadera y el compilador reemplazará a clHotlight
por su valor $00FF9933
donde aparezca en el código. Y para clLink
también.
Lea sobre esta pregunta SO ( en Delphi 7, ¿por qué puedo asignarle un valor a un const? ) Y todas las buenas respuestas allí ...
EDITAR: sobre TGUID ...
El problema es que escribir AdministratorGUID: TGUID = ''{DE44EEA0-6712-11D4-ADD4-0006295717DA}'';
no es apropiado
Está utilizando algo de magia de compilación para llamar a StringToGUID
detrás de la escena, lo que permite la conveniencia de expresar el GUID como una cadena que no son por naturaleza. Ellos son registros.
Entonces, probando AdministratorGUID = ''{DE44EEA0-6712-11D4-ADD4-0006295717DA}'';
no trabajará. Eso no es un GUID ...
Una solución alternativa es tener una constante y variables que apuntan a la misma área de memoria utilizando la directiva absolute
:
const
AdministratorGUID: TGUID = ''{DE44EEA0-6712-11D4-ADD4-0006295717DA}'';
var
SuperuserGUID: TGUID absolute AdministratorGUID; //alias of AdministratorGUID
RootGUID: TGUID absolute AdministratorGUID; //alias of AdministratorGUID
clHotlight: TColor = $00FF9933;
^
Declara clHotlight
como una '' variable '' (bueno, vale y una ''constante asignable'' si has permitido esto en las opciones del compilador) por medio de :
Como has encontrado, declaras:
clHotlight = TColor($00FF9933);
No hace ninguna asignación de clHotlight
hasta que se especifique más tarde.
Lo mismo aplica a su GUID.