20

Bedenken Sie:Delphi: Alle Konstanten sind konstant, aber einige sind konstanter als andere?

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

[Error] file.pas: Constant expression expected 

und die alternative Formulierung, die funktioniert:

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

Erklären.


Dann betrachten:

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

[Error] file.pas: Constant expression expected 

und beheben.

Bearbeiten: Stichwort const vor Deklarationen hinzugefügt; jemand glaubte nicht, dass sie const waren.

+0

Das hört sich für mich so an, als hätten Sie eine Hausaufgabe einfach ausgeschnitten und eingefügt, ohne sich die Mühe zu machen, sie ein wenig neu zu formulieren. –

+4

Nicht wirklich. Das ist nicht die Art von Sache, auf die Sie eine Hausaufgabe bekommen würden. Sieht für mich so aus, als wäre er in eine dunkle Ecke gewandert und bringt seine Frage nicht so gut wie möglich zum Ausdruck. –

+1

@Jerry Coffin: Ich hatte seit 1997 keine Hausaufgaben; Angenommen, das 4. Jahr EE-Projekt zählt als Hausaufgabe. –

Antwort

22

clHotlight: TColor = $00FF9933; ist keine Konstante, sondern eine typisierte Konstante (= statische Variable), d. H. Der Compiler reserviert einen Platz im Speicher für einen TColor, der zur Laufzeit den Wert $00FF9933 enthält.
Weil dieser Wert später geändert werden (mit der zuweisbaren Konst Option ON), ist es nicht eine echte Konstante und nicht in clLink = clHotLight; vom Compiler akzeptiert werden kann

clHotlight = TColor($00FF9933); ist streng die gleiche wie clHotlight = $00FF9933;
Es ist ein wahr ist Konstante und der Compiler ersetzt clHotlight durch seinen Wert $00FF9933, wo immer es im Code erscheint. Und für clLink auch.

liest auf diese Frage SO (In Delphi 7, why can I assign a value to a const?) und all die guten es Antworten ...

EDIT: über TGUID ...
Das Problem ist, dass AdministratorGUID: TGUID = '{DE44EEA0-6712-11D4-ADD4-0006295717DA}'; Schreiben nicht richtig ist.
Es verwendet einige Compiler Magie, StringToGUID hinter der Szene zu rufen, so dass die Bequemlichkeit die GUID als eine Zeichenfolge ausdrücken, die sie nicht von Natur aus sind. Sie sind Aufzeichnungen.

Also, versuchen AdministratorGUID = '{DE44EEA0-6712-11D4-ADD4-0006295717DA}'; wird nicht funktionieren. Das ist kein GUID ...

Eine Abhilfe ist eine typisierte Konstante und Variablen haben auf den gleichen Speicherbereich zeigt die absolute Direktive:

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

Ich sehe, was Sie und die andere SO Frage sagen, aber welche Syntax kann ich verwenden die TGUID, um die gewünschte Syntax zu erstellen, zB 'SuperuserGUID = AdministratorGUID; RootGUID = AdministratorGUID; '(dh wo die Konstante ein Datensatz ist) Oder ist das nicht möglich in Delphi? –

+0

Siehe meine Edit in der obigen Antwort. –

5
clHotlight: TColor = $00FF9933; 
     ^

bekannt, dass folgende clHotlight als 'Variable' (na ja, ok eine 'belegbare konstant', wenn Sie haben diese Optionen in Compiler erlaubt) mit Hilfe des :.

Wie Sie gefunden haben, erklärt:

clHotlight = TColor($00FF9933); 

macht keine Zuteilung von clHotlight, bis es später angegeben wird.

Das gleiche gilt für Ihre GUID.

+0

Aber ich habe die Option "Zuweisbare typisierte Konstanten" nicht aktiviert! :( –

+2

Das ist egal, Ian. Die Option steuert nur, ob sie zuweisbar sind. Es steuert nicht die Art, wie sie gespeichert sind. –

7

ich diesen Code versucht:

const 
    CAnswer1 = 42; 
    CAnswer2 : Integer = 42; 

    var 
    LAnswer : Integer; 

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

und hier ist der erzeugte Code:

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 

Sie haben Recht: einige Konstanten sind beständiger als andere. Die zweite Konstante wird tatsächlich vom Compiler als Variable behandelt.

+0

+1 für eine gute Menge an Arbeit und Proof-of-Concept-Erklärung –

1

willkommen zu Delphi Evolution . in delphi 1 & 2, können Sie keine initialen konstanten Wert zu einer globalen var zuweisen (zB: var xVar: Integer = 1). Die einzige Möglichkeit, dies zu tun, ist die Verwendung von const xVar: Integer = 1) und einige Codes, in denen Sie sie ändern können, wenn Sie möchten. Bis sie dieses alte Feature loswerden, können Sie das Konstrukt "const xVar: Integer" nicht als const-Wert verwenden.

Prost A Pham

4

Das Problem, weil eine Konstante ist nicht wirklich eine Konstante eingegeben entsteht, wie mit unterschiedlichem Grad der Klarheit und Erfolg von anderen erklärt.

Was noch nicht so ist, ist gezeigt, wie das Problem zu arbeiten (in einer großen Anzahl von Fällen), obwohl ein Paar Aufgeben greifbare Nähe kam, dass Geheimnis ... :)

In Ihrem spezieller Fall kann Sie durch die Umkehrung des „Aliasing“ des Wertes und die typisierten konstante Erklärung wie folgt, um das Problem zu bekommen:

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

clLink bietet jetzt Ihre wahre konstante und clHotlight ist die typisierte konstante, hat der gleiche Wert wie clLink.

für das die gleiche Technik GUID kann verwendet werden, aber man muss bedenken, den normalen konstanten Ausdruck einen typisierten GUID Konstante initialisieren - es wird nicht eine Aufzeichnung nicht verwendet, sondern eine einfache Zeichenkette, so:

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

HINWEIS: Solche GUID Konstanten sind perfekt einsetzbar in allen Orten, an denen TGUID ‚s benötigt werden, zB IsEqualGUID (TGUID, GUID_CONSTANT) usw.

+1

Leider ist es muddies die GUID-Deklaration wegen dieser Inkonsistenz: ID_CONSTANT ist eine Zeichenfolge und keine TGUID trotz einer Deklaration, die der typisierten const-Deklaration einer TGUID zu entsprechen scheint. –

+0

Ich bin mir nicht sicher wo/warum/wie es "matschig" gemacht wird. Ich kann nicht über eine Gelegenheit nachdenken, bei der ein wahrer "konstanter Ausdruck" -GUID-Wert erforderlich/nützlich wäre. Der übliche Ort, an dem dies auftritt, ist eine "case" -Anweisung, und Sie könnten einen GUID-Wert nicht "hinnehmen", selbst wenn es möglich wäre, echte konstante Datensätze zu deklarieren. – Deltics

+0

Wir verwenden ständig GUIDs die ganze Zeit. Am nützlichsten ist 'NULL_GUID: TGUID = '{00000000-0000-0000-0000-000000000000}'; wenn IsEqualGUID (Schlüssel, NULL_GUID) dann ". Ein anderes Beispiel ist das, das Sie gesehen haben, und überprüft, ob das Ding ein bestimmter vordefinierter Benutzer ist. Ein anderes Beispiel ist das Deklarieren einer konstanten COM ** clsid **, zB: 'CLASS_UIRibbonFramework: TGUID = '{926749FA-2615-4987-8845-C33E65F2B957}';' –

2

Die rechte Seite einer konstanten Erklärung einen „konstanten Ausdruck“ sein muss, die als „ein konstanter Ausdruck definiert ist, ist ein Ausdruck, der Compiler in das Programm ohne Ausführung auswerten wo es auftritt ". Sie können die gesamte akzeptierte Syntax für konstanten Ausdruck im Sprachführer finden. Beachten Sie, dass der Sprachenführer explizit angibt, dass typisierte Konstanten in konstanten Ausdrücken nicht auftreten können. - und deshalb scheitern Ihre Deklarationen, sowohl clHotlight: TColor = $ 00FF9933; und AdministratorGUID: TGUID = ...; sind typisierte Konstanten. Der Konstantenausdruck kann auch keine Funktionsaufrufe mit Ausnahme der im Sprachenführer aufgelisteten enthalten (z. B. Length(), SizeOf() und einige andere), die der Compiler zur Kompilierungszeit berechnen kann.Rewrite auf diese Weise :

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

Und es wird funktionieren.

Verwandte Themen