4

I wonder if I have found an Embarcadero compiler bug ...

The problem looks like it is related to generics.

Here is my source code

unit u_DateCount;

interface

uses
  SysUtils,
  u_JavaScriptable
  ;

type
  TDateCount = class (TJavaScriptable)
    strict private
    public
      NoOfSamples : Integer;
      TheDate : TDate;
      function ToString():String; override;
  end;

implementation

function TDateCount.ToString():String;
var
    myYear, myMonth, myDay : Word;
begin
    DecodeDate(TheDate, myYear, myMonth, myDay);
    Result := Format('[new Date(%d, %d ,0), %d]', [myYear, myMonth, NoOfSamples]);
end;

end.

unit u_Javascriptable;

interface

type
  TJavaScriptable = class
    strict private
    public
      function ToString:String; override;
  end;

implementation

function TJavaScriptable.ToString:String;
begin
    Result := '';
end;

end.

unit u_LineChart;

interface

uses
  System.IOUtils,
  SysUtils,
  System.Generics.Collections,
  u_JavaScriptable
  ;

type
  TLineChart<RecordType : TJavaScriptable> = class
    strict private
      Template : String;
      function ConvertRecordsToString():String;
    public
      Records : TList<RecordType>;
      function ToString():String;
      constructor Create(templatePath : String);
      destructor Destroy(); override;
  end;

implementation

function TLineChart<RecordType>.ConvertRecordsToString():String;
var
    I: Integer;
begin
    //Open brackets
    Result := '[ ';

    //The first record
    if Records.Count > 0 then
    begin
        Result := Result + Records[0].ToString();
    end;

    //Loop over records
    for I := 1 to Records.Count - 1 do
    begin
        Result := Result + ', ' + Records[I].ToString();
    end;

    //Close bracket
    Result := Result + ' ]';
end;

function TLineChart<RecordType>.ToString():String;
begin
    Result := Format(Template, [ConvertRecordsToString()]);
end;

constructor TLineChart<RecordType>.Create(templatePath : String);
begin
    inherited Create();
    Template := TFile.ReadAllText(templatePath);
    Records := TList<RecordType>.Create();
end;

destructor TLineChart<RecordType>.Destroy();
var
    I: Integer;
begin
    if Assigned(Records) then
    begin
        for I := 0 to Records.Count - 1 do
        begin
            Records[I].Destroy();
        end;
        Records.Clear();
        Records.Destroy();
        Records := nil;
    end;

    inherited;
end;

end.

And finally the main program

program Project4;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  u_Javascriptable in 'u_Javascriptable.pas',
  u_LineChart in 'u_LineChart.pas',
  u_DateCount in 'u_DateCount.pas';

var
   lineChart : TLineChart<TDateCount>;

begin

  lineChart := TLineChart<TDateCount>.Create('linechart.html');
  try


  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

The error message I get when I try to compile this is

[dcc32 Fatal Error] Project4.dpr(30): F2084 Internal Error: AV097530AC-R00000014-0

Usually when I see an error message similar to this, I can fix it by closing the embarcadero IDE and restarting it. However this did not seem to work this time.

4

3 回答 3

10

问题在于TLineChart<RecordType>.Destroy().

更改Records[I].Destroy();Records[I].Free();,它的工作原理。或者您只需正确执行并在构造函数中使用TObjectList<RecordType>.Create;,该构造函数负责在销毁列表时销毁其中的所有元素。

永远不要直接打电话Destroy。使用Free. 虽然它不应该导致编译器错误,但无论如何它都是错误的。

于 2013-09-09T06:36:17.227 回答
4

如果编译器报告“内部错误”,那始终是编译器错误。您应该为此在 QC 中打开一张票。希望他们可以为 XE5 修复它。

于 2013-09-09T06:01:27.897 回答
1

由于这适用于 XE3 但不适用于 XE4,我将假定这是一个 XE4 错误。在解决此问题之前,解决方案是使用不同版本的编译器,例如 XE3。

于 2013-09-09T05:48:25.673 回答