Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Unverständliche Fehlermeldung E2010 in Verbindung mit Varianten (https://www.delphipraxis.net/212662-unverstaendliche-fehlermeldung-e2010-verbindung-mit-varianten.html)

BigAl 13. Mär 2023 09:39

Delphi-Version: 5

Unverständliche Fehlermeldung E2010 in Verbindung mit Varianten
 
Hallo zusammen,

ich kämpfe schon seit ein paar Stunden mit einem eigenartigen Fehler, der vom Delphi-Compilers geworfen wird. Der Fehler kommt sowohl in Delphi 10 als auch 11. Ich habe den Code mal soweit reduziert wie irgend möglich um den Fehler zu reproduzieren:

Delphi-Quellcode:
program RecTest;

uses
  System.SysUtils,
  System.Variants;

type
  TMyClass = class
  public type
    TRec = record
      class operator Initialize(out Dest: TRec);
    end;
  private
    FRecs: TArray<TMyClass.TRec>;
  public
    procedure DoSomething;
  end;

class operator TMyClass.TRec.Initialize(out Dest: TRec);
begin
end;

procedure TMyClass.DoSomething;

  procedure PerformRec(ARec: TRec);
  begin
  end;

var
  V: Variant;
begin
  V.A.B := 5;

  for var Rec in FRecs do
    PerformRec(Rec);
end;

var
  MyClass: TMyClass;
begin
  MyClass := TMyClass.Create;
  try
    MyClass.DoSomething;
  finally
    MyClass.Free;
  end;
end.
Die Fehlermeldung lautet "[dcc32 Error] RecTest.dpr(34): E2010 Incompatible types: 'TVarData' and 'Pointer'" und wird immer beim "end" von "DoSomething" ausgegeben, uanabhängig was noch an Code in der Methode ist. Das "AVariant.A.B" ist im echten Programm z.B. ein Range-Object aus Excel. Sieht z.B. so aus:

Delphi-Quellcode:
AExcel.Range(2, Line, 3, Line).Borders[xlEdgeBottom].LineStyle := xlContinuous;
Ändere ich den Quelltext wie folgt, dann funktioniert es und es kommt keine Fehlermeldung:

Delphi-Quellcode:
procedure TMyClass.DoSomething;
type
  PRec = ^TRec;

  procedure PerformRec(ARecPtr: PRec);
  begin
  end;

var
  V: Variant;
begin
  V.A.B := 5;

  for var Rec in FRecs do
    PerformRec(@Rec);
end;
Auch wenn ich die Initialisierung aus TRec nehme kommt kein Fehler:

Delphi-Quellcode:
type
  TMyClass = class
  public type
    TRec = record
    end;
  private
    FRecs: TArray<TMyClass.TRec>;
  public
    procedure DoSomething;
  end;
Scheint also auch irgendwas mit managed Records zu tun zu haben.

Hat irgendwer eine Idee was das sein kann? Der Fehler wird sowohl vom Comiler als auch vom LSP angezeigt.

Uwe Raabe 13. Mär 2023 09:43

AW: Unverständliche Fehlermeldung E2010 in Verbindung mit Varianten
 
Der Fehler kommt auch nicht, wenn man die Variant-Zuweisung raus nimmt.

Update:
Delphi-Quellcode:
 V := 5      // geht
 V.A := 5    // geht
 V.A.B := 5; // geht nicht

BigAl 13. Mär 2023 09:46

AW: Unverständliche Fehlermeldung E2010 in Verbindung mit Varianten
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1519780)
Der Fehler kommt auch nicht, wenn man die Variant-Zuweisung raus nimmt.

Klar. Hatte ich vergessen. Aber das ist halt die Konstellation die ich im Programm habe. Das sieht dann im Programm z.B. so aus:

Delphi-Quellcode:
  ...
  AExcel.Cell[2, Line] := 'Content';
  AExcel.Range(2, Line, 3, Line).Font.Bold := True;
  AExcel.Range(2, Line, 3, Line).Borders[xlEdgeBottom].LineStyle := xlContinuous;
  AExcel.Range(2, Line, 3, Line).MergeCells := True;

  for var Page in FPages do
    ShowPages(Page, Line);

  // Show all parameters left aligned.
  AExcel.Range(CellStart, AExcel.Cell[2, Line]).HorizontalAlignment := xlLeft;
  ...

Uwe Raabe 13. Mär 2023 09:47

AW: Unverständliche Fehlermeldung E2010 in Verbindung mit Varianten
 
So geht's auch:

Delphi-Quellcode:
procedure TMyClass.DoSomething;

  procedure PerformRec(ARec: TRec);
  begin
  end;

  procedure SetVariant(var V: Variant);
  begin
    V.A.B := 5;
  end;

var
  V: Variant;
begin
  SetVariant(V);

  for var Rec in FRecs do
    PerformRec(Rec);
end;

Uwe Raabe 13. Mär 2023 09:49

AW: Unverständliche Fehlermeldung E2010 in Verbindung mit Varianten
 
Oder so:
Delphi-Quellcode:
procedure TMyClass.DoSomething;

  procedure PerformRec(ARec: TRec);
  begin
  end;

  procedure IterateRecs;
  begin
    for var Rec in FRecs do
      PerformRec(Rec);
  end;

var
  V: Variant;
begin
  V.A.B := 5;

  IterateRecs;
end;

Uwe Raabe 13. Mär 2023 09:51

AW: Unverständliche Fehlermeldung E2010 in Verbindung mit Varianten
 
Unabhängig von den Workarounds würde ich den Testcode in QP melden. Das sollen sich die Compiler-Freaks mal ansehen.

BigAl 13. Mär 2023 10:00

AW: Unverständliche Fehlermeldung E2010 in Verbindung mit Varianten
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1519784)
Unabhängig von den Workarounds würde ich den Testcode in QP melden. Das sollen sich die Compiler-Freaks mal ansehen.

Werde ich tun. Du hast mich aber auf eine Idee für einen Workaround gebracht der funktioniert:
Delphi-Quellcode:
procedure TMyClass.DoSomething;

  procedure PerformRec(ARec: TRec);
  begin
  end;

  procedure Blub;
  begin
    for var Rec in FRecs do
      PerformRec(Rec);
  end;

var
  V: Variant;
begin
  V.A.B := 5;
  Blub;
end;
Ist mir lieber als den Parameter als Pointer zu übergeben...

Ich brauche das "PerformRec" genau an dieser Stelle. Es handelt sich dabei um eine rekursive Prozedur die eine Baumstruktur verarbeitet. Diese sieht etwa so aus:
Delphi-Quellcode:
  procedure ShowPages(APage: TPage; var Line: Integer);
  begin
    { ... }
    Inc(Line);
    for var Page in APage.SubPages do
      ShowPages(Page, Line);
  end;

BigAl 13. Mär 2023 10:16

AW: Unverständliche Fehlermeldung E2010 in Verbindung mit Varianten
 
Hoffe das reicht so: RSP-41161

Uwe Raabe 13. Mär 2023 10:55

AW: Unverständliche Fehlermeldung E2010 in Verbindung mit Varianten
 
Sehr schön. Ich habe das mal entsprechend kommentiert.


Alle Zeitangaben in WEZ +1. Es ist jetzt 05:21 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