Компилятор генерирует неправильный код для shortstring
при использовании функцииЯвляется ли пользовательской ошибкой объявлять общую встроенную функцию `const` для короткой строки, или это ошибка компилятора?
function TTestObject<T>.Compare(const Left, Right: T): integer; inline;
Это Mangles параметры.
Следующий пример программы демонстрирует концепцию:
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
в общих функций, или это компилятор ошибка?
Bonus вопрос
Кроме ShortString, существуют другие типы, которые вызывают CompareFail
генерировать нерабочего код?
фон
Я не чувствую сильную потребности работать с shortstring
, но я пишу некоторую общую коду библиотеки и должен поддерживать все типы.
Обновление Это ошибка компилятора, которая была исправлена в 10.1 Berlin.
Почему вы используете '[ref]'. Это может привести только к более медленному коду. –
@DavidHeffernan Поскольку не используется '[ref]' приводит к неработоспособному коду :-(.Я не заметил разницы в скорости, хотя, будет дважды проверяться. – Johan
Объявление как 'CompareFail (var Left, Right: T) : integer; inline; 'работает хотя. –