为短字符串声明通用内联函数 `const` 是用户错误,还是编译器错误?

Is it a user error to declare a generic inline function `const` for shortstring, or is this a compiler bug?

编译器在使用函数

时为 shortstring 生成不正确的代码

function TTestObject<T>.Compare(const Left, Right: T): integer; inline;

它破坏了参数。

下面的示例程序演示了这个概念:

program ShortStringsAndConst;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

type
  TStr100 = string[100];

  TTestObject<T> = class
  private
    Bag1, Bag2: T;
    procedure RandomBags;
    procedure TestCompare;
    function CompareFail(const Left, Right: T): integer; inline;
    function CompareWin(const [ref] Left, Right: T): integer; inline;
  end;

var
  TestStr100: TTestObject<TStr100>;

  procedure Test;
  begin
    TestStr100:= TTestObject<TStr100>.Create;
    TestStr100.RandomBags;
    TestStr100.TestCompare;
  end;

{ TTestObject<T> }

procedure TTestObject<T>.RandomBags;
var
  a: integer;
begin
  PByteArray(@Bag1)^[0]:= SizeOf(T)- 1;
  for a:= 1 to SizeOf(T)- 1 do begin
    PByteArray(@Bag1)^[a]:= byte('a');
  end;
  Bag2:= Bag1;
end;

function TTestObject<T>.CompareFail(const Left, Right: T): integer;
var
  L,R: shortstring;
begin
  L:= PShortstring(@Left)^;
  R:= PShortstring(@Right)^;
  WriteLn(Format('Fail!! @Left = %p, @Right = %p, Left = %s, Right = %s',[@Left, @Right, L, R]));
end;

function TTestObject<T>.CompareWin(const [ref] Left, Right: T): integer;
var
  L,R: shortstring;
begin
  L:= PShortstring(@Left)^;
  R:= PShortstring(@Right)^;
  WriteLn(Format('Win:  @Left = %p, @Right = %p, Left = %s, Right = %s',[@Left, @Right, L, R]));
end;

procedure TTestObject<T>.TestCompare;
begin
  CompareFail(Bag1,Bag2);
  WriteLn;
  CompareWin(Bag1,Bag2);
  ReadLn;
end;

begin
  Test;
end.

问题
假设我可以在泛型函数中使用正常的 const 是我的错误,还是编译器错误?

加分题
除了 Shortstring 之外,还有其他类型会导致 CompareFail 生成非工作代码吗?

背景
我并不强烈需要使用 shortstring,但我正在编写一些通用库代码并且需要支持所有类型。

更新 这是一个编译器错误,已在 10.1 Berlin 中修复。

Is it an error on my part to assume I can get away with using normal const in generic functions, or is this a compiler bug?

假设你说的是真的,那么这是一个编译器错误。您需要报告错误并阻止使用短字符串。