Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Cast eines Arrays auf einen Arraytyp bedenklich? (https://www.delphipraxis.net/181894-cast-eines-arrays-auf-einen-arraytyp-bedenklich.html)

Neutral General 15. Sep 2014 20:55

Cast eines Arrays auf einen Arraytyp bedenklich?
 
Hallo,

Ich hätte da mal eine Frage. Folgende Typen:

Delphi-Quellcode:
TRecord = record
  // .. Daten
  RecordArray: Array of TRecord;
end;

TRecordArray = Array of TRecord;
Ich kann das TRecordArray im TRecord selbst nicht benutzen (von Pointern mal abgesehen), also benutze ich da ein einfaches Array of TRecord, was funktioniert. Ob das so schön ist.. wahrscheinlich gibts schöneres aber ich kenne keine bessere Lösung ohne Pointer/New/Dispose.

Aber weiter:

Des weiteren habe ich eine procedure die ungefähr so aussieht:

Delphi-Quellcode:
// Muss vom Typ TRecordArray sein, da SetLength mit "Array of TRecord" nicht funktioniert
procedure Irgendwas(var ARecords: TRecordArray)
begin
  SetLength(ARecords, 123); //
  // Array wird gefüllt
end;

// Aufruf
var Rec: TRecord;
begin
  // A: Die Typen der tatsächlichen und formalen Var-Parameter müssen übereinstimmen
  Irgendwas(Rec.RecordArray);

  // B: funktioniert
  Irgendwas(TRecordArray(Rec.RecordArray));
end;
Frage1: Gibt es ernsthafte Einsprüche zu dem Cast, weil die interne Struktur von "TRecordArray" und "Array of TRecord" möglicherweise unterschiedlich sind und es da zu unvorhergesehenen Fehlern kommen kann?

Frage2: Vorschläge zu einer bessere Lösung?

(Ich weiß der Titel ist sehr seltsam, aber konnte es nicht besser formulieren. Wenn jemand das Problem besser beschreiben kann - nur her damit :mrgreen: )

himitsu 15. Sep 2014 21:06

AW: Cast eines Arrays auf einen Arraytyp bedenklich?
 
Typen müssen nunmal identisch sein.
Delphi-Quellcode:
type
  TRecordArray = Array of TRecord; // geht natürlich nicht, da TRecord noch nicht deklariert ist und Forward-Deklarationen bei arrays nicht möglich sind (Größe/SizeOf muß vorhanden sein)
  TRecord = record
    // .. Daten
    RecordArray: TRecordArray;
  end;
Deine Definitionen sind zwar "intern gleich", aber nicht "identisch".
Jemand mit der selben DNA (Bauplan) wie du, ist ja dennoch nicht du.

Der Cast sollte kein Problem sein, da die Typen ja intern gleich, aber eben nicht der "selbe" Typ sind.

Sowas geht vermutlich auch nicht?
Delphi-Quellcode:
type
  TRecord = record
  public type
    TRecordArray = Array of TRecord;
  public
    // .. Daten
    RecordArray: TRecordArray;
  end;

procedure Irgendwas(var ARecords: TRecord.TRecordArray);
Am Sichersten wären hier wohl Pointertypen oder Objekte, welche als Forward deklariert werden können.
Oder du übergibst deinem Irgendwas nicht das Array, sondern den übergeordneten Record. :stupid:



Funktioniert auch, aber von der Typsicherheit her ein Graus, da man ja "alles" übergeben kann.
Delphi-Quellcode:
procedure Irgendwas(var ARecords);
begin
  SetLength(TRecordArray(ARecords), 123);
  // Array wird gefüllt
end;

procedure Irgendwas(var ARecords);
var
  TheRecords: TRecordArray absolute ARecords;
begin
  SetLength(TheRecords, 123);
  // Array wird gefüllt
end;

Der schöne Günther 15. Sep 2014 21:09

AW: Cast eines Arrays auf einen Arraytyp bedenklich?
 
Vielleicht schon zu spät für mich, aber warum nicht
Delphi-Quellcode:
TArray<TRecord>
statt
Delphi-Quellcode:
array of TRecord
?

Delphi-Quellcode:
program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

type
  TRecord = record
     // .. Daten
     RecordArray: TArray<TRecord>
  end;
  TRecordArray = TArray<TRecord>;

procedure Irgendwas(var ARecords: TRecordArray);
begin
   SetLength(ARecords, 123); //
   // Array wird gefüllt
end;

// Aufruf
var Rec: TRecord;
begin
   // A: Funktioniert
  Irgendwas(Rec.RecordArray);


   // B: funktioniert
   //Irgendwas(TRecordArray(Rec.RecordArray));
end.

himitsu 15. Sep 2014 21:20

AW: Cast eines Arrays auf einen Arraytyp bedenklich?
 
Zitat:

Zitat von Der schöne Günther (Beitrag 1272674)
Vielleicht schon zu spät für mich, aber warum nicht
Delphi-Quellcode:
TArray<TRecord>
statt
Delphi-Quellcode:
array of TRecord
?

Hmmm, joar ... manchmal vergisst man was wann war.

Delphi 2010 und Generics? ... war hoffentlich doch schon 2007/2009 :gruebel:
Hoffentlich waren da auch schon die einzelnen TArray<T>-Deklaratationen "identisch".

Der schöne Günther 15. Sep 2014 21:27

AW: Cast eines Arrays auf einen Arraytyp bedenklich?
 
Nein, muss nicht. Ich achte mittlerweile nicht mehr drauf, was jemand in seinem Profil eingetragen hat da es eigentlich nie stimmt.

himitsu 15. Sep 2014 21:34

AW: Cast eines Arrays auf einen Arraytyp bedenklich?
 
Die lügen alle? :shock:

Dann hatt'er halt Pech (wenn man es nicht abweichend im Post erwähnt) :angel2:

Neutral General 15. Sep 2014 22:21

AW: Cast eines Arrays auf einen Arraytyp bedenklich?
 
Zitat:

Zitat von himitsu (Beitrag 1272673)
Oder du übergibst deinem Irgendwas nicht das Array, sondern den übergeordneten Record.

Jo das ginge eigentlich auch :mrgreen:
Der Rest deiner Vorschläge ist wie du schon selbst gesagt hast etwas doof.
Da ist der Cast dann doch einfacher/schöner.

Wenns intern keine Probleme gibt ist ja gut :)
Ja benutze (privat) Delphi 2010 und da gibts schon Generics ;) Generics gibts seit 2009 ;)
Von daher wäre TArray<TRecord> tatsächlich auch ne gute Idee.

Wobei ich den Code möglicherweise nach C++ übersetzen muss und da sollte ich keine zu Delphi-spezifischen Kram einbauen wenn ichs mir nicht unnötig schwer machen will.

Danke auf jeden Fall für eure Antworten! :)

BUG 15. Sep 2014 23:34

AW: Cast eines Arrays auf einen Arraytyp bedenklich?
 
Zitat:

Zitat von Neutral General (Beitrag 1272682)
Wobei ich den Code möglicherweise nach C++ übersetzen muss und da sollte ich keine zu Delphi-spezifischen Kram einbauen wenn ichs mir nicht unnötig schwer machen will.

Wenn du nicht anfängst mit RTTI rumzubasteln (über dynamische Cast hinaus), sollte es für viele grundlegende Sachen einfach zu findende Entsprechung geben.
Gerade Container-Klassen und darauf laufende Algorithmen gibt es in der STL genug :)

Code:
class TRecord {
public:
  std::vector<TRecord> RecordArray;
};

void irgendwas(std::vector<TRecord>& aVector)
{
  aVector.resize(123);
  // Array wird gefüllt
}

Namenloser 15. Sep 2014 23:44

AW: Cast eines Arrays auf einen Arraytyp bedenklich?
 
Das sollte im Prinzip sicher sein. Du musst nur aufpassen, dass du "array of ..." nicht bei Parametern verwendest, denn diese Arrays haben ein anderes Format, was zu Fehlern führen wird.

Delphi-Quellcode:
type
  TRecordArray = array of TRecord;

procedure DoSomething(Foo: array of TRecord);
var
  Bar: TRecordArray;
begin
  // Das NICHT tun
  Bar := TRecordArray(Foo);
  SetLength(Bar, 42);
end;

Dejan Vu 16. Sep 2014 07:09

AW: Cast eines Arrays auf einen Arraytyp bedenklich?
 
[QUOTE[
Frage1: Gibt es ernsthafte Einsprüche zu dem Cast, weil die interne Struktur von "TRecordArray" und "Array of TRecord" möglicherweise unterschiedlich sind und es da zu unvorhergesehenen Fehlern kommen kann?[/QUOTE] Ja. Casts sind hässlich, nicht typsicher und führen zu unvorhergesehenen Fehlern. Den letzten Punkt habe ich von einem an sich pfiffigen Programmierer ;-) Ich würde mich -außer beim Experimentieren- nie drauf verlassen, das sich interne Datenstrukturen nicht doch irgendwann ändern.

Zitat:

Frage2: Vorschläge zu einer bessere Lösung?
Klassen und typsichere Listen.

Meine Frage lautet: Wieso willst Du so etwas überhaupt anstellen? Wieso willst Du auf New/Dispose und Pointer verzichten? Was ist der Unterschied zwischen dem und einem 'SetLength'?

Delphi-Quellcode:
// Übrigens, statt:
Procedure Irgendwas (FooListe : TRecordArray); // oder Array of TRecord? Hilfäääää 

// einfach den Record als Parameter übergeben
Procedure Irgendwas (Rec : TRecord);
// Damit hat sich das Problem in Luft aufgelöst


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:54 Uhr.
Seite 1 von 2  1 2      

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