Konstanten

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
charlytango
Beiträge: 1014
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
CPU-Target: Win 32/64, Linux64
Wohnort: Wien

Konstanten

Beitrag von charlytango »

Mir ist beim Lesen des englischen Forums ein Stück Code aufgefallen, das ich so noch nicht kannte und deswegen thematisiere. Es geht um den Einsatz einer Konstante in einer Ereignisprozedur.

Code: Alles auswählen

procedure TForm1.FormActivate(Sender: TObject);
const first: boolean = true;
begin
 writeln('FormActivate');
 if not first then exit;

 first:=false;  
 writeln('DoSomething');
end;
Es soll damit FormActivate nur das erste mal aufgerufen werden, aber das Konstukt mit const hat mich etwas stutzig gemacht.
Denn warum darf man einer Konstante einen Wert zuweisen und warum funktioniert das Konstrukt, denn es wird anstandslos kompiliert.

Beim Nachforschen bin ich auf folgendes gestoßen:

Die Zuweisung `first := false;` funktioniert, weil `first` nicht nur eine Konstante ist, sondern auch eine lokale Variable. Die `const`-Deklaration `const first: boolean = true;` initialisiert die Variable `first` beim kompilieren nur einmal mit dem Wert `true`, aber sie macht sie nicht unveränderlich.
Die `const`-Deklaration wird jedoch ignoriert, und die Variable `first` bleibt eine normale Variable.

Der Geltungsbereich von 'first' scheint auch auf die Prozedur beschränkt zu sein.
Um das gleiche zu erreichen hätte ich eine Variable in der Unit definiert und sie im FormCreate Initialisiert.
Das Konstrukt ist also wohl eine elegante Ausreizung der Sprachmöglichkeiten mit besserer Lesbarkeit - oder gibt es dazu andere Meinungen?

Soner
Beiträge: 711
Registriert: Do 27. Sep 2012, 00:07
OS, Lazarus, FPC: Win10Pro-64Bit, Immer letzte Lazarus Release mit SVN-Fixes
CPU-Target: x86_64-win64
Wohnort: Hamburg

Re: Konstanten

Beitrag von Soner »

Das hatten wir schon mal, lies die Antworten auf meiner Frage.

wp_xyz
Beiträge: 5049
Registriert: Fr 8. Apr 2011, 09:01

Re: Konstanten

Beitrag von wp_xyz »

charlytango hat geschrieben: Do 12. Dez 2024, 08:28

Code: Alles auswählen

procedure TForm1.FormActivate(Sender: TObject);
const first: boolean = true;
begin
 writeln('FormActivate');
 if not first then exit;

 first:=false;  
 writeln('DoSomething');
end;
Ich finde das mit dem const extrem unschön und verwirrend. Obiges "first" z.B. ist wegen "const" eine globale Variable, die aber nur aus FormActivate heraus ansprechbar ist und bei jedem Aufruf von FormActivate ihren Wert behält. Schreibst du aber "var: boolean = true" ("var" statt "const") hast du eine lokale Variable, die bei jedem Aufruf von FormActivate neu mit dem Wert true initialisiert wird.

Benutzeravatar
Zvoni
Beiträge: 171
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit
Wohnort: BW

Re: Konstanten

Beitrag von Zvoni »

Hinzu kommt, dass durch den Datentyp Boolean, das Ding ne Adresse im Speicher erhält, im Gegensatz zu untypisierten Konstanten, bei denen der Compiler deren Wert im Code einfach dann ersetzt.

Aus dem Stegreif weiss ich jetzt aber auch nicht, was der Default ist: Writable Const on oder off

Stimme aber zu, dass in dem Kontext "Const" sehr unglücklich gewählt ist, da es ja eigentlich eher sowas wie "Static" beschreibt, was ich aus VB6 kenne:
Eine Prozedur-lokale Variable, die ihren letzten Wert behält
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Benutzeravatar
theo
Beiträge: 10699
Registriert: Mo 11. Sep 2006, 19:01

Re: Konstanten

Beitrag von theo »

charlytango hat geschrieben: Do 12. Dez 2024, 08:28 Das Konstrukt ist also wohl eine elegante Ausreizung der Sprachmöglichkeiten mit besserer Lesbarkeit - oder gibt es dazu andere Meinungen?
Widersprichst du dir da nicht selber?
Eine bessere Lesbarkeit hat es wohl kaum, wenn man zuerst (oder jedes Mal?) die Regeln zu diesem merkwürdigen Spezialfall nachlesen muss.
Persönlich würde ich dieses Konstrukt meiden.

charlytango
Beiträge: 1014
Registriert: Sa 12. Sep 2015, 12:10
OS, Lazarus, FPC: Laz stable (2.2.6, 3.x)
CPU-Target: Win 32/64, Linux64
Wohnort: Wien

Re: Konstanten

Beitrag von charlytango »

Soner hat geschrieben: Do 12. Dez 2024, 11:38 Das hatten wir schon mal, lies die Antworten auf meiner Frage.
Danke, war sehr informativ.
theo hat geschrieben: Do 12. Dez 2024, 11:53 Eine bessere Lesbarkeit hat es wohl kaum, wenn man zuerst die Regeln zu diesem merkwürdigen Spezialfall nachlesen muss.
Persönlich würde ich dieses Konstrukt meiden.
Auch wenns irgendwie elegant aussieht, ich lasse sicherheitshalber die Finger davon ;-)
Für mich ist der Fall damit erledigt.

Benutzeravatar
Zvoni
Beiträge: 171
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz 2.2.2 FPC 3.2.2)
CPU-Target: 32Bit
Wohnort: BW

Re: Konstanten

Beitrag von Zvoni »

charlytango hat geschrieben: Do 12. Dez 2024, 11:57 Auch wenns irgendwie elegant aussieht, ich lasse sicherheitshalber die Finger davon ;-)
Warum?
Ist eine elegante Methode z.B. um in einem Timer eine lokale Variable hochlaufen zu lassen oder bei Rekursionen die Tiefe zu "messen"
(und ja, ich weiss... "Dann nimm halt ne unit-weite Variable unter implementation..."),

Aber wie bereits erwähnt: "Man muss es halt wissen....."
Ein System sie alle zu knechten, ein Code sie alle zu finden,
Eine IDE sie ins Dunkel zu treiben, und an das Framework ewig zu binden,
Im Lande Redmond, wo die Windows drohn.

Mathias
Beiträge: 6695
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Konstanten

Beitrag von Mathias »

Ich finde das mit dem const extrem unschön und verwirrend. Obiges "first" z.B. ist wegen "const" eine globale Variable, die aber nur aus FormActivate heraus ansprechbar ist und bei jedem Aufruf von FormActivate ihren Wert behält. Schreibst du aber "var: boolean = true" ("var" statt "const") hast du eine lokale Variable, die bei jedem Aufruf von FormActivate neu mit dem Wert true initialisiert wird.
Ich finde dies auch extrem unschön. Wieso kann man in Pascal nicht einfach das Schlüsselwort static einführen. So ist es für jedermann lesbar.
Wenigsten geht die unterdessen ich classen und objecten.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

PascalDragon
Beiträge: 901
Registriert: Mi 3. Jun 2020, 07:18
OS, Lazarus, FPC: L 2.0.8, FPC Trunk, OS Win/Linux
CPU-Target: Aarch64 bis Z80 ;)
Wohnort: München

Re: Konstanten

Beitrag von PascalDragon »

Mathias hat geschrieben: Do 12. Dez 2024, 14:11
Ich finde das mit dem const extrem unschön und verwirrend. Obiges "first" z.B. ist wegen "const" eine globale Variable, die aber nur aus FormActivate heraus ansprechbar ist und bei jedem Aufruf von FormActivate ihren Wert behält. Schreibst du aber "var: boolean = true" ("var" statt "const") hast du eine lokale Variable, die bei jedem Aufruf von FormActivate neu mit dem Wert true initialisiert wird.
Ich finde dies auch extrem unschön. Wieso kann man in Pascal nicht einfach das Schlüsselwort static einführen. So ist es für jedermann lesbar.
Weil es eben das const-Konstrukt gibt und das würde auch nicht verschwinden, weil es ja alten Code und v.a. TP und Delphi Code gibt, der das braucht. Wir vermeiden es im Allgemeinem mehrere Syntaxen für das Gleiche zu haben.
FPC Compiler Entwickler

Warf
Beiträge: 2080
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Konstanten

Beitrag von Warf »

Nicht getestet, aber wenn man's unbedingt will müsste doch sowas möglich sein

Code: Alles auswählen

{$Macros On}
{$define staticvar:={$J+}const}
{$define constval:={$J-}const}

...
constval
  c: Char = 'c';
staticvar
  i: Integer= 42;

Antworten