Delphi数据类型太大:柏林更新2中超过2 GB

sha*_*ful 9 delphi freepascal lazarus delphi-10.1-berlin

我有一个适用于Delphi和Lazarus的单元.在Lazarus中,该单元编译时没有任何异常,但在Delphi中它给出了错误数据类型太大:超过2 GB.以下是代码:

unit UType;

{$ifdef FPC}
 {$MODE delphi}{$H+}
{$endif}

interface


type
  TFreqType = Extended;

  TFreqCutArray = Array [0..0]of TFreqType;

  PFreqCutArray = ^TFreqCutArray;

  FilterOrder = Integer;

  TAS_Sample = Extended;

  TAS_SampleArray = Array[0..High(Integer) div Sizeof(TAS_Sample) - 1] of TAS_Sample;

  PTAS_SampleArray = ^TAS_SampleArray;

  TAS_Float = Extended;

  TComplex = record
    Re, Im: TAS_Sample; // Z = Re + i*Im
    end;

  PComplex = ^TComplex;
  TComplexArray = Array[0..High(Integer) div Sizeof(TComplex) - 1] of TComplex;//here Delphi gives the error

  PComplexArray = ^TComplexArray;
  FilterProc = function(V: TAS_Sample): TAS_Sample of object;

implementation

end.
Run Code Online (Sandbox Code Playgroud)

我正在使用柏林更新2,在Lazarus中使用相同的代码进行编译,没有任何错误.

Dav*_*nan 9

这似乎是一个编译器缺陷.你可以声明这样的类型:

TComplexArray = Array[0..67108862] of TComplex;
Run Code Online (Sandbox Code Playgroud)

并且编译器将接受声明.请注意67108862 = High(Integer) div Sizeof(TComplex) - 1.

您可以通过声明常量来避免对上限进行硬编码:

const
  ComplexArrayUpperBound = High(Integer) div Sizeof(TComplex) - 1;

type
  TComplexArray = Array[0..ComplexArrayUpperBound] of TComplex;
Run Code Online (Sandbox Code Playgroud)

如今,这种类型的声明非常不合时宜.我强烈建议您使用动态数组.这些将为您提供动态内存的自动清理,并允许编译器为您的所有阵列访问添加范围检查代码.后一点很重要,因为它会为您提供代码中边界错误的早期警告.

如果您没有分配数组而是声明这些类型以启用数组索引,那么它可能更容易使用{$POINTERMATH ON}.

此外,我建议您使用Double而不是Extended.您不太可能需要10字节Extended类型并切换到Double一半的内存需求.由于对齐,您的TComplex大小为32字节,但Double基于版本的是16字节.由于更好地使用缓存,这种节省将带来显着的性能优势.