为短字符串声明通用内联函数 `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?
假设你说的是真的,那么这是一个编译器错误。您需要报告错误并阻止使用短字符串。
编译器在使用函数
时为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?
假设你说的是真的,那么这是一个编译器错误。您需要报告错误并阻止使用短字符串。