array of Record mit Konstanten nicht möglich?

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1639
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

array of Record mit Konstanten nicht möglich?

Beitrag von fliegermichl »

Irgendwie raff ich es grad nicht.

Code: Alles auswählen

type
  RColorRec = packed record
   Color,                          // Normale Flächenfarbe
   MarkedColor,                    // Fläche ist markiert
   SelectedColor,                  // Fläche ist selektiert
   MarkedSelectedColor : TColor;   // Fläche ist markiert und selektiert
  end;

const
 RedOutSideColor  : RColorRec = (Color : $FF0000; MarkedColor : $ED12CC; SelectedColor : $0A10F5; MarkedSelectedColor : $895AA5);
 RedInsideColor   : RColorRec = RedOutSideColor; // <- Hier meckert der Compiler, dass er eine ( erwartet!?
 
RedOutsideColor ist doch vom Typ RColorRec und auch bereits initialisiert.

Benutzeravatar
Zvoni
Beiträge: 363
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: array of Record mit Konstanten nicht möglich?

Beitrag von Zvoni »

Ich bekomme bei dem hier "Illegal Expression"

Code: Alles auswählen

Const
 a:Integer=10;
 b:Integer=a;      
Logische Schlussfolgerung?
Typisierte Konstanten können nicht gegenseitig zur Initialisierung verwendet werden (Weil sie eine Speicher-Adresse haben?)

P.S.: Was hat das mit Array of Records zu tun?
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
fliegermichl
Lazarusforum e. V.
Beiträge: 1639
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: array of Record mit Konstanten nicht möglich?

Beitrag von fliegermichl »

Zvoni hat geschrieben: Mi 19. Mär 2025, 11:45 Ich bekomme bei dem hier "Illegal Expression"

Code: Alles auswählen

Const
 a:Integer=10;
 b:Integer=a;      
Logische Schlussfolgerung?
Typisierte Konstanten können nicht gegenseitig zur Initialisierung verwendet werden (Weil sie eine Speicher-Adresse haben?)

P.S.: Was hat das mit Array of Records zu tun?
Aber der Compiler kann doch zur Compilezeit den zu initialisierenden Inhalt feststellen. Wieso soll das nicht möglich sein?

Benutzeravatar
Zvoni
Beiträge: 363
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: array of Record mit Konstanten nicht möglich?

Beitrag von Zvoni »

fliegermichl hat geschrieben: Mi 19. Mär 2025, 12:12 Aber der Compiler kann doch zur Compilezeit den zu initialisierenden Inhalt feststellen. Wieso soll das nicht möglich sein?
Würde prinzipiell erst mal zustimmen, aber.... *schulterzuck*...
mal schauen ob PascalDragon hier reinschaut...

EDIT:
Hmmmmmm ... --> https://www.freepascal.org/docs-html/ref/refse10.html
Remark It should be stressed that typed constants are automatically initialized at program start.
Initialisierung erfolgt bei Programm-Start! Also nicht beim Kompilieren!
Wohl eben weil typisierte Konstanten eine Speicher Adresse haben, und WELCHE Adresse das dann ist, kann ja der Compiler zur Compile-Time nicht wissen! Erst zur Runtime.

Ist zumindest meine Schlussfolgerung.
Heisst: Deine RedOutSideColor-Konstante erhält ihre "Werte" auch erst bei Programmstart
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
m.fuchs
Lazarusforum e. V.
Beiträge: 2805
Registriert: Fr 22. Sep 2006, 19:32
OS, Lazarus, FPC: Winux (Lazarus 2.0.10, FPC 3.2.0)
CPU-Target: x86, x64, arm
Wohnort: Berlin
Kontaktdaten:

Re: array of Record mit Konstanten nicht möglich?

Beitrag von m.fuchs »

Zvoni hat geschrieben: Mi 19. Mär 2025, 11:45 Logische Schlussfolgerung?
Typisierte Konstanten können nicht gegenseitig zur Initialisierung verwendet werden (Weil sie eine Speicher-Adresse haben?)
Klar können Kosntanten zur gegenseitigen Intialisierungen verwendet werden, man muss halt auch Konstanten verwenden:

Code: Alles auswählen

program ConstTest;
const
  a = 10;
  b = a;

begin
  WriteLn(b);
end.
Problem ist: eine typisierte Const unter Borland-Abkömmlingen von Pascal ist keine Konstante, sondern eine statische Variable. Das Verhalten kann man mit

Code: Alles auswählen

{$J-}
zwar ausschalten - dann kann man nicht mehr schreibend auf sie zugreifen - aber das löst dann trotzdem das obige Problem nicht.

Bitte einmal kräftig den Verantwortlichen bei Borland verfluchen, der diesen Quark gebaut hat der uns schon seit Jahrzehnten auf die Füße fällt.
Software, Bibliotheken, Vorträge und mehr: https://www.ypa-software.de

Benutzeravatar
Zvoni
Beiträge: 363
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: array of Record mit Konstanten nicht möglich?

Beitrag von Zvoni »

m.fuchs hat geschrieben: Mi 19. Mär 2025, 12:53 Klar können Kosntanten zur gegenseitigen Intialisierungen verwendet werden, man muss halt auch Konstanten verwenden:

Code: Alles auswählen

program ConstTest;
const
  a = 10;
  b = a;

begin
  WriteLn(b);
end.
Ja, untypisierte Konstanten (!!), weil der Compiler zur Compile-Time dann das Symbol im Quelltext mit dem Wert ersetzt.
Auch daran erkennbar, dass untypisierte Konstanten keine Speicheradresse haben.

Code: Alles auswählen

program Project1;
Const
  a=42;
  b=a;
begin
  Writeln(a);
  Writeln(PtrUint(@b));
  Readln;
end.
-->
project1.lpr(7,20) Error: Can't take the address of constant expressions
Hier kein Compile-Error. Funzt

Code: Alles auswählen

program Project1;
Const
  a:Integer=42;
begin
  Writeln(a);
  Writeln(PtrUint(@a));
  Readln;
end.
Zuletzt geändert von Zvoni am Mi 19. Mär 2025, 13:47, insgesamt 1-mal geändert.
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: 6899
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: array of Record mit Konstanten nicht möglich?

Beitrag von Mathias »

Dies hier geht als Alternative, wen man Pointer nimmt:

Code: Alles auswählen

type
  TVector3f = array[0..2] of single;
  PVector3f = ^TVector3f;

const
  {$push,}{$J-}
  vec3blue: TVector3f = (0.0, 0.0, 1.0);
  vec3green: TVector3f = (0.0, 1.0, 0.0);
  vec3red: TVector3f = (1.0, 0.0, 0.0);
  {$J+}{$pop}

const
  colors: array of PVector3f = (@vec3blue, @vec3green, @vec3red);
Edit:
Der Trick funktioniert auch beim Beispiel des Threed-Erstellers.

etwas anderes würde ja gar kein Sinn machen, dann wäre den Record doppelt im Speicher.

Code: Alles auswählen

type
  TColorRec = packed record
   Color,                          // Normale Flächenfarbe
   MarkedColor,                    // Fläche ist markiert
   SelectedColor,                  // Fläche ist selektiert
   MarkedSelectedColor : TColor;   // Fläche ist markiert und selektiert
  end;
  PColorRec=^TColorRec;
const
 RedOutSideColor  : TColorRec = (Color : $FF0000; MarkedColor : $ED12CC; SelectedColor : $0A10F5; MarkedSelectedColor : $895AA5);
 RedInsideColor   : PColorRec = @RedOutSideColor; // <- Hier meckert der Compiler, dass er eine ( erwartet!?  
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

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

Re: array of Record mit Konstanten nicht möglich?

Beitrag von Warf »

Das liegt einfach daran wie der Initialisierungscode geschrieben ist. Der parser schreibt den Inhalt direkt als konstanten ins assembly ohne Programmcode zu generieren, weshalb Copy Operationen nicht durchgeführt werden. Deshalb funktionieren auch keine management Operatoren mit Initialisierung, oder auch Default Initialisierung.

Das ist denke ich mal keine aktive design Entscheidung, sondern eher das Ergebnis der aktuellen Implementierung die gar nicht so trivial zu ändern ist

PascalDragon
Beiträge: 945
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: array of Record mit Konstanten nicht möglich?

Beitrag von PascalDragon »

fliegermichl hat geschrieben: Mi 19. Mär 2025, 10:50 RedOutsideColor ist doch vom Typ RColorRec und auch bereits initialisiert.
Du kannst nur untypisierte Konstanten verwenden, um andere Werte (egal ob Variablen oder Konstanten) zu initialisieren. Das war schon immer so und wird (voraussichtlich) auch immer so bleiben.
Warf hat geschrieben: Mi 19. Mär 2025, 16:59 Das ist denke ich mal keine aktive design Entscheidung, sondern eher das Ergebnis der aktuellen Implementierung die gar nicht so trivial zu ändern ist
Es war in so fern eine aktive Designentscheidung als dass TP und Delphi sich hier genauso verhalten. Falls sich hier mal was ändert, dann dass die untypisierten Konstanten im Format von Extended Pascal erweitert werden. Diese könnten dann als Initialisierer genutzt werden.
FPC Compiler Entwickler

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1639
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: array of Record mit Konstanten nicht möglich?

Beitrag von fliegermichl »

Mathias hat geschrieben: Mi 19. Mär 2025, 13:45
etwas anderes würde ja gar kein Sinn machen, dann wäre den Record doppelt im Speicher.

Code: Alles auswählen

type
  TColorRec = packed record
   Color,                          // Normale Flächenfarbe
   MarkedColor,                    // Fläche ist markiert
   SelectedColor,                  // Fläche ist selektiert
   MarkedSelectedColor : TColor;   // Fläche ist markiert und selektiert
  end;
  PColorRec=^TColorRec;
const
 RedOutSideColor  : TColorRec = (Color : $FF0000; MarkedColor : $ED12CC; SelectedColor : $0A10F5; MarkedSelectedColor : $895AA5);
 RedInsideColor   : PColorRec = @RedOutSideColor; // <- Hier meckert der Compiler, dass er eine ( erwartet!?  
[/code]
Nicht wirklich. Ich möchte ja schon unterschiedliche Records haben. Sie sollten nur mit den gleichen Werten initialisiert werden. Der Anwender soll dann schon die Möglichkeit haben, die Innenseite unterschiedlich zur Aussenseite einzufärben. Klar, ich könnte eine Initialisierungsfunktion schreiben und da dann Move(OutSideColors, InsideColors, SizeOf(RColorRec));
aber dann kann ich auch gleich die erste Zeile kopieren und Out durch In ersetzen.

Antworten