Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Konstantes Array of Record deklarieren (https://www.delphipraxis.net/217463-konstantes-array-record-deklarieren.html)

dummzeuch 3. Jul 2025 17:24

Delphi-Version: 12 Athens

Konstantes Array of Record deklarieren
 
Ich stehe gerade auf dem Schlauch.

Ich will ein dynamisches Array von Records als Konstante deklarieren. Eigentlich dachte ich, das geht so:

Delphi-Quellcode:
type
  TKameraTypRec = record
    Name: string;
    Breite: Integer;
    Hoehe: Integer;
    PixelSizeX: Extended;
    PixelSizeY: Extended;
  end;
  TKameraTypArr = array of TKameraTypRec;

const
  CAM_TYPES: TKameraTypArr = (
    (Name: 'GT1920'; // <== Compilefehler hier
     Breite: 1920;
     Hoehe: 1080;
     PixelSizeX: 0.00000586;
     PixelSizeY: 0.00000586)
    );
Aber der Compiler in Delphi 12 ist anderer Meinung:
Code:
[dcc32 Error] wf_Kamera.pas(84): E2003 Undeclared identifier: 'Name'
Erst, wenn ich explizit eine Array-Länge setze, funktioniert es:

Delphi-Quellcode:
type
  TKameraTypArr = array[0..0] of TKameraTypRec;
const
  CAM_TYPES: TKameraTypArr = (
    (Name: 'GT1920'; Breite: 1920; Hoehe: 1080; PixelSizeX: 0.00000586; PixelSizeY: 0.00000586)
    );
Ich dachte, das war eine der Neuerungen in einer der letzten Delphi-Versionen, dass man bei Array-Konstanten keine Länge mehr angeben muss???

:gruebel:

Uwe Raabe 3. Jul 2025 17:47

AW: Konstantes Array of Record deklarieren
 
So sollte es gehen:
Delphi-Quellcode:
const
  CAM_TYPES_0: TKameraTypRec =
     (Name: 'GT1920'; // <== Compilefehler hier
     Breite: 1920;
     Hoehe: 1080;
     PixelSizeX: 0.00000586;
     PixelSizeY: 0.00000586
    );

const
  CAM_TYPES: TKameraTypArr = [CAM_TYPES_0];

himitsu 3. Jul 2025 17:59

AW: Konstantes Array of Record deklarieren
 
Typisierte Konstanten sind IMMER "schreibgeschützte" Variaben.

Bei Strings, geht die Referenzzählung auf -1, für Konstanten ... bei Arrays klappt hier die Deklaration meistens nicht, für dynamische Arrays.


Wenn das NEUE, was der Vorgänger zeigt, klappt, dann hast du Glück.



Man kann hier zwar auch tricksen, aber du willst bestimmt nicht böse Casten und als Dummy die Arraystrucktur selbst zusammenklöppeln?

TomyN 5. Jul 2025 21:51

AW: Konstantes Array of Record deklarieren
 
Hmm, Name wird fett dargestellt, ist das evtl. ein reserviertes Wort?

himitsu 5. Jul 2025 22:33

AW: Konstantes Array of Record deklarieren
 
Ja/Nein.
Das Highlighting im Forum arbeitet auch etwas anders, als das in der Delphi-IDE
und selbst das Highlighting in der IDE ist nicht immer korrekt.

Dennis07 9. Jul 2025 23:10

AW: Konstantes Array of Record deklarieren
 
Zitat:

Zitat von dummzeuch (Beitrag 1549959)
Ich dachte, das war eine der Neuerungen in einer der letzten Delphi-Versionen, dass man bei Array-Konstanten keine Länge mehr angeben muss???

Derzeit deklarierst du einen dynamischen Array-Typ, allerdings ein statisches Array. Deklariere
Delphi-Quellcode:
TKameraTypRec
mal als statischen Array-Typ. Dann klappt das auch:
Delphi-Quellcode:
//TKameraTypArr = array of TKameraTypRec;
TKameraTypArr = array [0..0] of TKameraTypRec;
Selbst falls du es kompiliert bekommen hättest, hätte der Compiler ja spätestens bei den runden Klammern (
Delphi-Quellcode:
(...)
) gemeckert, weil diese nur für statische Array-Konstanten zulässig sind. Du hättest eckige Klammern (
Delphi-Quellcode:
[...]
) verwenden müssen. Dass das mit dynamischen Array-Konstanten so nicht klappt hat leider mit dem Fakt zu tun, dass diese intern ganz anders gespeichert werden als statische Array-Konstanten. Es sind eigentlich nur Konstante Zeiger auf eine anonyme dynamische Array-Variable. Du kannst die Beschränkung mit Inline-Variablen umgehen, dann sollte es funktionieren, aber würde den Ramen sprengen.

Zitat:

Zitat von himitsu (Beitrag 1549962)
Typisierte Konstanten sind IMMER "schreibgeschützte" Variaben.

Nicht "IMMER", aber man kann sagen "immer". Großgeschrieben deshalb nicht, weil das mit dem "schreibgeschützt" halt so pauschal auch nicht stimmt. Deshalb kannst du mit dynamischen Array-Konstanten auch so viel lustigen Schindluder wie den hier treiben:
Delphi-Quellcode:
const
  A: TArray<Char> = ['H', 'E', 'L', 'L', 'O'];
begin
  Writeln(A[0] + A[1] + A[2] + A[3] + A[4]); // >>HELLO
  A[0] := 'W';
  A[1] := 'O';
  A[2] := 'R';
  A[3] := 'L';
  A[4] := 'D';
  Writeln(A[0] + A[1] + A[2] + A[3] + A[4]); // >>WORLD
end.
Zitat:

Zitat von TomyN (Beitrag 1549981)
Hmm, Name wird fett dargestellt, ist das evtl. ein reserviertes Wort?

Nein, ist es nicht. Du kannst es ja auch gern anstatt mit
Delphi-Quellcode:
Name
mit dem Feld
Delphi-Quellcode:
Breite
versuchen und wirst merken, dass es genauso wenig funktioniert.

Zitat:

Zitat von himitsu (Beitrag 1549982)
und selbst das Highlighting in der IDE ist nicht immer korrekt.

Mein Favorit in Delphi ist bis heute:
Delphi-Quellcode:
property add
, aus irgendeinem mir nicht erklärlichen Grund wird dort (und zwar nur dort) der Begriff
Delphi-Quellcode:
add
hervorgehoben... :-D

Stevie 9. Jul 2025 23:54

AW: Konstantes Array of Record deklarieren
 
Zitat:

Zitat von dummzeuch (Beitrag 1549959)
Ich will ein dynamisches Array von Records als Konstante deklarieren.

Geht nicht, weil

freimatz 10. Jul 2025 08:05

AW: Konstantes Array of Record deklarieren
 
Hallo,
ich verstehe noch nicht, wieso das überhaupt gehen sollte. Für mich ist "konstant" und "dynamisch" ein Widerspruch.
Wenn es eine Konstante sein soll, dann kann man doch auch ein festes Arry machen - oder nicht?

himitsu 10. Jul 2025 09:35

AW: Konstantes Array of Record deklarieren
 
OK, sagen wir es so
Es sind IMMER Konstanten, wo der Compiler versucht da einen Schreibschutz draufzulegen.
* es gibt Sonderfälle und Bugs,
* und via Pointerrumgefummel kann man das auch umgehen

Besonders geil ist es, wenn man ausversehn die Konstante Delphi-Referenz durchsuchenEmptyStr mit überschreibt.
(z.B. DevExpress-Grids zeigen dann in NULL-Spalten plözlich etwas an)

dummzeuch 10. Jul 2025 09:35

AW: Konstantes Array of Record deklarieren
 
Zitat:

Zitat von freimatz (Beitrag 1550076)
ich verstehe noch nicht, wieso das überhaupt gehen sollte. Für mich ist "konstant" und "dynamisch" ein Widerspruch.
Wenn es eine Konstante sein soll, dann kann man doch auch ein festes Arry machen - oder nicht?

Es geht um die reine Bequemlichkeit. Ich weiß nicht von vorneherein, wie viele Einträge das Array hat und will das erst durch die Angabe in der Konstanten festlegen. Und wenn ich später einen weiteren Record hinzufüge, möchte ich nicht erst die Array-Größe ändern.

Für einfache Datentypen (z.B. array of integer) geht das ja, nur eben nicht mit einem array of Record.

himitsu 10. Jul 2025 11:58

AW: Konstantes Array of Record deklarieren
 
Auch das Thema mehrere Entwickler und Mergen, spielt gern eine Rolle.

Zwei Kollegen fügen je eine "Zeile" / Eintrag hinzu, dann müssten sie ja, bei einem statischen Array die Größe definieren, was sich nach dem Merge aber wiederspricht.

Stevie 10. Jul 2025 12:02

AW: Konstantes Array of Record deklarieren
 
Zitat:

Zitat von freimatz (Beitrag 1550076)
ich verstehe noch nicht, wieso das überhaupt gehen sollte. Für mich ist "konstant" und "dynamisch" ein Widerspruch.
Wenn es eine Konstante sein soll, dann kann man doch auch ein festes Arry machen - oder nicht?

"Konstant" und "Dynamisch" sind hier wohl die falschen Worte - es geht eher darum, dass es kein "fixed-size" Array ist und somit auch potenziell zuweisungskompatibel zu einer
Delphi-Quellcode:
array of T
oder
Delphi-Quellcode:
TArray<T>
Variablen oder Parameter.

Die Technik hinter einem "konstanten dynamischen" Array ist dieselbe, wie bei einem konstanten String bzw Stringliteral - der Compiler legt dadurch, dass er -1 in das RefCount Feld schreibt, fest, dass es sich um eine "Konstante" handelt, von der in bestimmten Fällen eine Kopie gemacht werden muss.

Zitat:

Zitat von Uwe Raabe (Beitrag 1549960)
So sollte es gehen

Nein,
Delphi-Quellcode:
E2026 Constant expression expected

Dennis07 10. Jul 2025 12:24

AW: Konstantes Array of Record deklarieren
 
Zitat:

Zitat von freimatz (Beitrag 1550076)
Hallo,
ich verstehe noch nicht, wieso das überhaupt gehen sollte. Für mich ist "konstant" und "dynamisch" ein Widerspruch.
Wenn es eine Konstante sein soll, dann kann man doch auch ein festes Arry machen - oder nicht?

Das Gegenteil von konstant ist variabel.
Das Gegenteil von statisch ist dynamisch.

Zumindest in dieser Konstellation, und es ist wichtig, dass du genau darauf achtest. Es gibt folgende Konstellationen:
  • statische Array-Konstanten:
    Delphi-Quellcode:
    const A: array [0..1] of Byte = (-128, 127)
  • dynamische Array-Konstanten:
    Delphi-Quellcode:
    const A: array of Byte = [-128, 127]
  • statische Array-Variablen:
    Delphi-Quellcode:
    var A: array [0..1] of Byte
  • dynamische Array-Variablen:
    Delphi-Quellcode:
    var A: array of Byte

Der einzige Unterschied für den Programmierer ist, dass du bei dynamischen Arrays keine Länge angeben brauchst, sondern diese automatisch gesetzt wird (damals brauchte man
Delphi-Quellcode:
SetLength
, das geht heute aber auch ohne):
Delphi-Quellcode:
var
  A: array of Byte;
begin
  // früher:
  // SetLength(A, 2);
  // A[0] := -128;
  // A[1] := 127;
  // oder, falls man einen Typen hatte:
  // A := TBytes.Create(-128, 127);
  // Braucht man heute alles nicht mehr, einfach:
  A := [-128, 127];
end;
Genau das gleiche trifft auch auf die Konstanten zu: Hier ist der einzige Unterschied, dass du keine explizite Längenangabe in der Deklaration mehr brauchst.*

*) Und noch ein paar Unterschiede in der Speicherverwaltung, aber die sind jetzt mal egal.

Hinzu kommt noch ein Sonderfall: Dynamische Array-Inline-Konstanten. Darauf wollte ich jetzt eigentlich nicht eingehen, aber weil es anscheinend doch noch zu einer belebten Diskussion gekommen ist, hier mal ein Lösungsansatz:
Delphi-Quellcode:
type
  TKameraTypRec = record
    Name: string;
    Breite: Integer;
    Hoehe: Integer;
    PixelSizeX: Extended;
    PixelSizeY: Extended;
    // Implementierung der Factory-Methode dürfte selbsterklärend sein:
    class function Create(const AName: String; const ABreite, AHoehe: Integer; const APixelsSizeX, APixelsSizeY: Extended): TKameraTypRec; static;
    // Du kannst natürlich stattdessen auch eine globale Routine nehmen, ist ja das selbe wie eine statische Klassenfunktion
  end;

begin
  const CAM_TYPES: TKameraTypArr {Typen könntest du dank Inferenz sogar weglassen, lol} = [
    TKameraTypRec.Create('GT1920', 1920, 1080, 0.00000586, 0.00000586)
  ];
  // ...
end.
So geht das theoretisch. Ob es jetzt geiler ist als da eben eine Länge vor zu schreiben muss jeder für sich selbst entscheiden.

Uwe Raabe 10. Jul 2025 13:32

AW: Konstantes Array of Record deklarieren
 
Zitat:

Zitat von Stevie (Beitrag 1550073)
Zitat:

Zitat von dummzeuch (Beitrag 1549959)
Ich will ein dynamisches Array von Records als Konstante deklarieren.

Geht nicht, weil

Yo, den hatte ich ganz vergessen. :roll:


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:58 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz