Forward Deklaration von record wie bei class

Für Fragen zur Programmiersprache auf welcher Lazarus aufbaut
Antworten
Mathias
Beiträge: 7230
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Forward Deklaration von record wie bei class

Beitrag von Mathias »

Bei Classen kann man dies elegant so lösen

Code: Alles auswählen

type
  TClass2 = class;

  TClass1 = class(TObject)
    c: TClass2;
  end;

// Hier kann alles ,mögliche sein.
const
  s1 = 'Ich bin irgendwas';
  
  procedure blabla; cdecl; external;

type
  TClass2 = class(TObject)
    c: TClass1;
  end;
Geht sowas auch irgendwie mit einem Record ?
Sowas geht nicht:

Code: Alles auswählen

type
  Prec2 = record;

  TRec1 = record
    r: PRec2;
  end;
  PRec1 = ^TRec1;

// Hier soll noch Zeugs rein.

const
  s2 = 'Ich bin irgendwas';
  
  procedure blabla; cdecl; external;

type
  TRec2 = record
    r: PRec1;
  end;
  PRec2 = ^TRec2;
Was ich kenne ist folgendes, aber dann darf nicht mal ein Schlüsselwort type dazwischen stehen.

Code: Alles auswählen

type
  PRec2 = ^TRec2;
  PRec1 = ^TRec1;

  TRec1 = record
    r: PRec2;
  end;

  TRec2 = record
    r: PRec1;
  end;
Gibt es für record auch sowas elegantes wie mit class ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot


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

Re: Forward Deklaration von record wie bei class

Beitrag von Mathias »

theo hat geschrieben: So 1. Mär 2026, 10:20 https://gitlab.com/freepascal.org/fpc/s ... sues/24425
Das man Trec nicht in Trec dekalrieren kann ist klar, das wurde den record rekursiv Vergrößerern.
Aber das Beispiel mit den property, ,müsste eigentlich gehen, ich sehe da nirgends was rekursives.

Mir geht es um sowas mit Pointern.

Code: Alles auswählen

type
  Prec2 = record;

  TRec1 = record
    r: PRec2;
  end;
  PRec1 = ^TRec1;

// Hier soll noch Zeugs rein.

const
  s2 = 'Ich bin irgendwas';
  
  procedure blabla; cdecl; external;

type
  TRec2 = record
    r: PRec1;
  end;
  PRec2 = ^TRec2;
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

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

Re: Forward Deklaration von record wie bei class

Beitrag von fliegermichl »

Mathias hat geschrieben: So 1. Mär 2026, 17:11
theo hat geschrieben: So 1. Mär 2026, 10:20 https://gitlab.com/freepascal.org/fpc/s ... sues/24425
Das man Trec nicht in Trec dekalrieren kann ist klar, das wurde den record rekursiv Vergrößerern.
Aber das Beispiel mit den property, ,müsste eigentlich gehen, ich sehe da nirgends was rekursives.

Mir geht es um sowas mit Pointern.

Code: Alles auswählen

type
  Prec2 = record;

  TRec1 = record
    r: PRec2;
  end;
  PRec1 = ^TRec1;

// Hier soll noch Zeugs rein.

const
  s2 = 'Ich bin irgendwas';
  
  procedure blabla; cdecl; external;

type
  TRec2 = record
    r: PRec1;
  end;
  PRec2 = ^TRec2;
Mit einem Pointer auf TRec2 geht es doch.

Code: Alles auswählen

type
  PRec2 = ^TRec2;

  TRec1 = record
    somefield : integer;
    p2 : PRec2;
  end;

  TRec2 = record
    eini : integer;
  end;
compiliert einwandfrei.

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

Re: Forward Deklaration von record wie bei class

Beitrag von Mathias »

Mit einem Pointer auf TRec2 geht es doch.
Dies habe ich im ersten Post erwähnt. Aber das geht nur wen nichts dazwischen ist.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

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

Re: Forward Deklaration von record wie bei class

Beitrag von fliegermichl »

Mathias hat geschrieben: So 1. Mär 2026, 19:10
Mit einem Pointer auf TRec2 geht es doch.
Dies habe ich im ersten Post erwähnt. Aber das geht nur wen nichts dazwischen ist.
Wieso? Das geht doch:

Code: Alles auswählen

program Project1;
type
  PRec2 = ^TRec2;

  TTest = class
    fI : Integer;
  end;

  TRec1 = record
    somefield : integer;
    p2 : PRec2;
  end;

  TNocheinTest = class
    fJ : integer;
  end;

  TRec2 = record
    eini : integer;
  end;

var r1 : TRec1;
begin
 new(r1.p2);
 r1.p2^.eini := 1;
end. 

Benutzeravatar
Zvoni
Beiträge: 568
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz/FPC fixes)
CPU-Target: 64Bit
Wohnort: BW

Re: Forward Deklaration von record wie bei class

Beitrag von Zvoni »

fliegermichl hat geschrieben: Mo 2. Mär 2026, 11:56
Mathias hat geschrieben: So 1. Mär 2026, 19:10
Mit einem Pointer auf TRec2 geht es doch.
Dies habe ich im ersten Post erwähnt. Aber das geht nur wen nichts dazwischen ist.
Wieso? Das geht doch:
Ja, solange alles innerhalb derselben "Type"-Sektion ist.

Sein Problem ist folgendes

Code: Alles auswählen

Type
  Typ1-Record
Const
  Irgendeine Const
Type --> Neue "Type"-Section
  Typ2-Record

Und da geht es eben nicht
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: 1757
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Forward Deklaration von record wie bei class

Beitrag von fliegermichl »

Zvoni hat geschrieben: Mo 2. Mär 2026, 12:24 ...
Und da geht es eben nicht
Achso. Naja, dann definiert man es eben in der gleichen type Section.
Wieso es in einer weiteren aber nicht geht, erschließt sich mir aber nicht wirklich.

Benutzeravatar
Zvoni
Beiträge: 568
Registriert: Fr 5. Jul 2024, 08:26
OS, Lazarus, FPC: Windoof 10 Pro (Laz/FPC fixes)
CPU-Target: 64Bit
Wohnort: BW

Re: Forward Deklaration von record wie bei class

Beitrag von Zvoni »

fliegermichl hat geschrieben: Mo 2. Mär 2026, 14:45
Zvoni hat geschrieben: Mo 2. Mär 2026, 12:24 ...
Und da geht es eben nicht
Achso. Naja, dann definiert man es eben in der gleichen type Section.
Wieso es in einer weiteren aber nicht geht, erschließt sich mir aber nicht wirklich.
Wobei es in der Doku eigentlich erklärt ist: https://www.freepascal.org/docs-html/re ... 3-630003.5
When the compiler encounters a typed pointer declaration where the referenced type is not yet known, it postpones resolving the reference till later. The pointer definition is a “Forward type declaration”.

The referenced type should be introduced later in the same Type block. No other block may come between the definition of the pointer type and the referenced type. Indeed, even the word Type itself may not re-appear: in effect it would start a new type-block, causing the compiler to resolve all pending declarations in the current block.
Zu Deutsch:
Immer wenn eine neue Type-Section "eröffnet" wird, versucht der Compiler alle bisherigen Referenzen/Deklarationen in der aktuellen type-Section aufzulösen, was in diesem Fall halt knallt.
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: 1757
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Forward Deklaration von record wie bei class

Beitrag von fliegermichl »

Hmm, wieso geht sowas dann mit Klassen?
Das folgende compiliert fehlerfrei.

Code: Alles auswählen

program Project1;

type
  tfirst = class;

  tescond = class
    ffirst : TFirst;
  end;

const
  s = 'Hallo';

type
  tfirst = class

  end;

begin

end.

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

Re: Forward Deklaration von record wie bei class

Beitrag von Mathias »

Hmm, wieso geht sowas dann mit Klassen?
Genau das meine ich.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

PascalDragon
Beiträge: 1032
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: Forward Deklaration von record wie bei class

Beitrag von PascalDragon »

Mathias hat geschrieben: Mo 2. Mär 2026, 19:24
Hmm, wieso geht sowas dann mit Klassen?
Genau das meine ich.
fliegermichi fragt warum das Auflösen von Vorwärtsdeklarationen zwischen type-Bereichen für Klassen funktioniert, aber nicht für Records (Delphi, TP, Mode TP und Mode Delphi unterstützen es weder für Klassen noch für Records).
Was du fragst ist warum Records keine Vorwärtsdeklarationen an sich erlauben und das liegt daran, dass der Compiler für die Verwendung des Recordtypen die Größe wissen muss. Für Zeiger ist dies jedoch nicht nötig, da die Größe eines Zeigers immer bekannt ist. Und Variablen und Parameter mit einem Klassentyp sind immer implizit Zeiger, deswegen kann der Compiler da auch ohne Probleme Vorwärtsdeklarationen anbieten.
FPC Compiler Entwickler

Antworten