Dynamische Array und Pointer Vermischung

Für Fehler in Lazarus, um diese von anderen verifizieren zu lassen.
Mathias
Beiträge: 7292
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Dynamische Array und Pointer Vermischung

Beitrag von Mathias »

Gerade habe ich keinen FPC zur Hand, habt ihr mal Versucht nil zu Typecasten?
Wie ich es erwartet habe:

Code: Alles auswählen

  var
    p: PInteger;
  begin
    p := Pointer(nil);    // Geht
    p := PInteger(nil);   // Geht
    p := PByte(nil);      // Geht nicht
Du kannst Pointer auch mit Array-Syntax verwenden:
Bei C-Bindungen ist dies gang un gäbe.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

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

Re: Dynamische Array und Pointer Vermischung

Beitrag von Warf »

Socke hat geschrieben: Mo 4. Mai 2026, 12:10 Du kannst Pointer auch mit Array-Syntax verwenden:

Code: Alles auswählen

var
  p: PInteger;
begin
  p[20] := 15;
end;
Basierend auf dem Basistypen errechnet der Compiler dann automatisch die Speicheradresse. Im Gegensatz zu Arrays fällt dann aber die Speicherveraltung, Größeninformationen und ggf. RangeChecking weg.
Wobei das nicht der "klassische" Pascal Weg ist und auch nicht in allen modi geht (ich glaube bei Mode Delphi geht es nur für basis typen). Ursprünglich konnte Pascal ja auch keine Pointer Arithmetik. Der eigentlich "vorgesehene" Weg ist der cast in einem statischen Array:

Code: Alles auswählen

PIntegerArray(MyPointer)^[20] := 15;
Dabei ist IntegerArray in der RTL Definiert als (auf 32 bit):

Code: Alles auswählen

type IntegerArray = array [0..$effffff] of Integer;

PascalDragon
Beiträge: 1040
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: Dynamische Array und Pointer Vermischung

Beitrag von PascalDragon »

theo hat geschrieben: So 3. Mai 2026, 11:54
Mathias hat geschrieben: So 3. Mai 2026, 11:43 Aber müsste FPC in meinem Beispiel nicht mindestens einen cast verlangen ?
Ja, ist schon etwas merkwürdig.
Vielleicht kann PascalDragon das erklären.
Nil ist wie Warf erwähnt hat nicht ein Pointer per se, sondern ein spezieller Wert (und ein reserviertes Wort), der je nach Kontext eine entsprechende Bedeutung hat.
FPC Compiler Entwickler

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

Re: Dynamische Array und Pointer Vermischung

Beitrag von Mathias »

Nil ist wie Warf erwähnt hat nicht ein Pointer per se, sondern ein spezieller Wert (und ein reserviertes Wort), der je nach Kontext eine entsprechende Bedeutung hat.
Nur das klärt nicht das Problem vom ersten Post.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 7299
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Dynamische Array und Pointer Vermischung

Beitrag von af0815 »

Mathias hat geschrieben: Mi 13. Mai 2026, 13:09
Nil ist wie Warf erwähnt hat nicht ein Pointer per se, sondern ein spezieller Wert (und ein reserviertes Wort), der je nach Kontext eine entsprechende Bedeutung hat.
Nur das klärt nicht das Problem vom ersten Post.
Bei dem Beispiel stimmen alle Typen, wo soll da jetzt das Problem liegen ?
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

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

Re: Dynamische Array und Pointer Vermischung

Beitrag von Mathias »

Bei dem Beispiel stimmen alle Typen, wo soll da jetzt das Problem liegen ?
Dies hier, mindestens ein cast sollte verlangt werden.

Code: Alles auswählen

type
  TdBodyID = Pointer;

  function CreateBalls: TdBodyID;
  begin
    Result := nil;
  end;

const
  COUNT = 3;
var
  ball: array of TdBodyID = nil;
begin
  ball := CreateBalls;  // Wieso geht dies
end.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

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

Re: Dynamische Array und Pointer Vermischung

Beitrag von Zvoni »

Hat das was mit zu tun, dass die Adresse der Array-Variablen selbst dieselbe ist wie die Adresse des ersten Elements?

Also wie man es von C her kennt: Die Array-Variable selbst zeigt auf das erste Element des Arrays vom Element-Typ TdBodyID.
Und im Beispiel hätten sie eben implizit denselben Datentypen
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: 7292
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Dynamische Array und Pointer Vermischung

Beitrag von Mathias »

Beispiel hätten sie eben implizit denselben Datentypen
Aber nur wen es so ist:

Code: Alles auswählen

  ball[i] := CreateBalls; 
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
kupferstecher
Beiträge: 439
Registriert: Do 17. Nov 2016, 11:52

Re: Dynamische Array und Pointer Vermischung

Beitrag von kupferstecher »

Es gibt halt keine Typüberprüfung, und dann gilt wohl folgendes:
"Dynamic arrays are reference counted. Calling setLength(myDynamicArrayVariable, 0) virtually does myDynamicArrayVariable := nil and decreases the reference count."
Ist aus dem Link von Theo in der ersten Antwort.
Die Zuweisung von nil setzt also die Anzahl Arrayelemente auf 0.

https://wiki.freepascal.org/Dynamic_array

Eigentlich denke ich auch, dass das nicht erlaubt sein sollte. Die Referenzzählung ist bzw. sollten Compilerinternas sein, auf die man so keinen direkten Zugriff hat. Aber vermutlich gibt es auch irgendeinen Spezialfall, wo man das sinnvoll einsetzen kann.
--
Zurzeit verwende ich Pointer recht intensiv, um Binärdaten zu verarbeiten. Da ist Typsicherheit nicht sinnvoll, da sich die Typen in den Daten erst beim Parsen ergeben. Ein häufiger Fehler von mir dabei ist, dass an der falschen Stelle Werte statt Adressen übergeben werden oder die Adresse eines Pointers anstatt die Pointerreferenz übergeben wird. Ich denke da sollte der Compiler unterstützen und Zuweisungen nur erlauben, wenn es sich um die gleiche Art Adresse/Wert handelt. Also dass ein Ordinalwert nicht einfach einem Pointer zugewiesen werden kann, die Adresse eines Pointers nicht einem Pointer und ein Pointer nicht einem Pointer auf einen Pointer.

@PascalDragon: Überseh ich da etwas?

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

Re: Dynamische Array und Pointer Vermischung

Beitrag von fliegermichl »

Naja, ein Pointer auf einen Pointer ist eben ein Pointer und bei der Zuweisung von Ordinalwerten an Pointer und umgekehrt, gibt der Compiler Warnungen aus.
Man muss in diesem Bereich eben wissen, was man so macht.

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

Re: Dynamische Array und Pointer Vermischung

Beitrag von Mathias »

Naja, ein Pointer auf einen Pointer ist eben ein Pointer
Da bin ich anderer Meinung, was dieses Beispiel beweist.

Code: Alles auswählen

var
  p: Pointer = nil;
  i: PInteger = nil;
  c: pchar = nil;

begin
  p := i;     // geht
  i := p;     // geht
  p := c;     // geht
  c := p;     // geht
  c := i;     // geht nicht !
end.              
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

PascalDragon
Beiträge: 1040
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: Dynamische Array und Pointer Vermischung

Beitrag von PascalDragon »

Mathias hat geschrieben: Mi 13. Mai 2026, 13:09
Nil ist wie Warf erwähnt hat nicht ein Pointer per se, sondern ein spezieller Wert (und ein reserviertes Wort), der je nach Kontext eine entsprechende Bedeutung hat.
Nur das klärt nicht das Problem vom ersten Post.
Wieso? Leere dynamische Arrays sind definiert als Nil, daher ist Nil natürlich ein gültiger Wert für ein solches Array.
FPC Compiler Entwickler

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

Re: Dynamische Array und Pointer Vermischung

Beitrag von theo »

Die Frage dreht sich aber nicht um Nil, sondern um TdBodyID, den Rückgabetyp von function CreateBalls

Antworten