Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Delphi kann keine Arrays konkatenieren wenn... (https://www.delphipraxis.net/183851-delphi-kann-keine-arrays-konkatenieren-wenn.html)

Der schöne Günther 9. Feb 2015 20:04

Delphi-Version: XE7

Delphi kann keine Arrays konkatenieren wenn...
 
Ich verstehe die Welt nicht mehr.

Folgende Konsolenanwendung:
Delphi-Quellcode:
program Project24;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  Unit10 in 'Unit10.pas';
begin
  try
   concatenateBytes();
  except
   on E: Exception do
     Writeln(E.ClassName, ': ', E.Message);
  end;
  readln;
end.
Unit10.pas:
Delphi-Quellcode:
unit Unit10;

interface uses System.SysUtils;


   (* type TSomeClass = class(TObject)
      class function getSomeBytes(): TBytes; virtual; abstract;
   end; *)

   function concatenateBytes(): TBytes;

implementation uses System.IOUtils;

function concatenateByteS(): TBytes;
   var
      firstArray, secondArray: TBytes;
   begin
      firstArray := TFile.ReadAllBytes(ParamStr(0));
      secondArray := TFile.ReadAllBytes(ParamStr(0));
      concatenateBytes := firstArray + secondArray;

   end;

end.
Ausführen. Läuft durch. Nun entfernen wir einmal den Kommentar um
Delphi-Quellcode:
TSomeClass
. Das Ausführen von
Delphi-Quellcode:
concatenateBytes
verursacht nun eine AV. Kann mir das jemand erklären? Wtf?

Daniel 9. Feb 2015 20:16

AW: Delphi kann keine Arrays konkatenieren wenn...
 
Putzig.
Allerdings kannte ich bisher nur den expliziten Weg über SetLength():

Delphi-Quellcode:
function concatenateByteS : TBytes;
   var
      firstArray, secondArray: TBytes;
   begin
      firstArray := TFile.ReadAllBytes('C:\Development\DelphiLib\FastMM\FastMM4_FAQ.txt');
      secondArray := TFile.ReadAllBytes('C:\Development\DelphiLib\FastMM\FastMM4_FAQ.txt');

      SetLength(result, Length(firstArray) + Length(secondArray));
      Move(firstArray[0], result[0], Length(firstArray));
      Move(secondArray[0], result[Length(firstArray)], Length(secondArray));
      //result := firstArray + secondArray;
   end;
Der geht.
Ich hielte es bislang auch für einen Fehler, auf SetLength() zu verzichten.

Der schöne Günther 9. Feb 2015 20:19

AW: Delphi kann keine Arrays konkatenieren wenn...
 
Ja, das wäre auch mein "Workaround" nachdem ich erst einmal schauen musste wie die Welt vor XE7 Arrays konkateniert hat. Aber verstehen was da für verrückte Dinge ablaufen tue ich nicht im geringsten :roteyes:

Wir haben doch hier Assembler-Spezialisten. Ob einer aus dem generierten Code mit und ohne
Delphi-Quellcode:
TSomeClass
schlau wird?

Ist ja nicht so als hätte mich die Fehlersuche mindestens eine halbe Stunde gekostet. AAARGH

mkinzler 9. Feb 2015 20:22

AW: Delphi kann keine Arrays konkatenieren wenn...
 
Was für eine Exception?
Funktioniert es mit der Klasse ohen abstrakte Methode?

Wenn ich mir Dein 2. Beispel anschaue vermute ich mal du wolltset im 1. ParamStr(1) statt ParamStr(0) schreiben, den ParamStr(0) ist ja die Exe selber.

jaenicke 9. Feb 2015 21:27

AW: Delphi kann keine Arrays konkatenieren wenn...
 
Ich würde das für einen Compilerfehler halten...
Code:
Unit28.pas.19: firstArray := TFile.ReadAllBytes('J:\Eigene Dokumente\...');
004D3A42 8D55F8           lea edx,[ebp-$08]
004D3A45 B8A83A4D00       mov eax,$004d3aa8
004D3A4A E891F9FFFF      call TFile.ReadAllBytes
Unit28.pas.20: secondArray := TFile.ReadAllBytes('J:\Eigene Dokumente\...');
004D3A4F 8D55F4           lea edx,[ebp-$0c]
004D3A52 B8343B4D00       mov eax,$004d3b34
004D3A57 E884F9FFFF      call TFile.ReadAllBytes
Unit28.pas.21: Result := firstArray + secondArray;
004D3A5C A19C3AA100       mov eax,[$00a13a9c]    // <-- diese Zeilen
004D3A61 50               push eax               // <-- diese Zeilen
004D3A62 8B45FC          mov eax,[ebp-$04]
004D3A65 8B4DF4           mov ecx,[ebp-$0c]
004D3A68 8B55F8           mov edx,[ebp-$08]
004D3A6B E87081F3FF      call @DynArrayCat3
Unit28.pas.23: end;
004D3A70 33C0             xor eax,eax
004D3A72 5A              pop edx
004D3A73 59               pop ecx
004D3A74 59               pop ecx
Die einzige Änderung zwischen mit und ohne der Klassendeklaration ist die Adresse in dem mov. Mit Klassendeklaration steht an der Adresse bei mir z.B. ein String mit einer Umgebungsvariable. :shock:
Eigentlich sollte da aber der Pointer auf die RTTI des dynamischen Arrays stehen, das da verkettet wird... sprich von TBytes. Mit der Klassendeklaration stimmt dieser Zeiger nicht.

Hintergrund:
DynArrayCat3 bekommt vier Parameter, deshalb landet der vierte Parameter, also der Typpointer, auf dem Stack, daher das push.

Uwe Raabe 9. Feb 2015 21:29

AW: Delphi kann keine Arrays konkatenieren wenn...
 
So geht's auch:

Delphi-Quellcode:
function concatenateByteS(): TBytes;
var
  resArray,
  firstArray,
  secondArray: TBytes;
begin
  firstArray := TFile.ReadAllBytes(ParamStr(1));
  secondArray := TFile.ReadAllBytes(ParamStr(1));
  resArray := TFile.ReadAllBytes(ParamStr(1));
  result := resArray;
end;
Machst du einen Bugreport dazu auf?

Stevie 9. Feb 2015 21:52

AW: Delphi kann keine Arrays konkatenieren wenn...
 
Statt der Klasse reicht auch schon:

Delphi-Quellcode:
var
  x: TBytes;
Das Vorkommen von TBytes an anderer Stelle im Interface Teil scheints da beim Codegen zu zersägen.

jaenicke 9. Feb 2015 22:28

AW: Delphi kann keine Arrays konkatenieren wenn...
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1289324)
Machst du einen Bugreport dazu auf?

Habe ich mal gemacht:
https://quality.embarcadero.com/browse/RSP-10051
Die Verwendung von TArray<Byte> bringt den gleichen Fehler, das Beispiel ist so und mit Verwendung der simplen Variablen wie Stevie meinte noch simpler.

Uwe Raabe 9. Feb 2015 22:45

AW: Delphi kann keine Arrays konkatenieren wenn...
 
Der 64-Bit Compiler scheint es richtig zu machen.

Der schöne Günther 10. Feb 2015 08:04

AW: Delphi kann keine Arrays konkatenieren wenn...
 
Erinnert irgendwie daran wie DCC32 auch dabei versagte, zwei Strings mit der selben Länge zu konkatenieren, DCC64 es aber hinbekam (siehe hier)

Danke fürs das Zusammenkürzen des Beispiels. War für mich gestern schon zu spät dafür :drunken:


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:27 Uhr.

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