2015-06-28 8 views
2

Компилятор генерирует неправильный код для 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.

+0

Почему вы используете '[ref]'. Это может привести только к более медленному коду. –

+0

@DavidHeffernan Поскольку не используется '[ref]' приводит к неработоспособному коду :-(.Я не заметил разницы в скорости, хотя, будет дважды проверяться. – Johan

+0

Объявление как 'CompareFail (var Left, Right: T) : integer; inline; 'работает хотя. –

ответ

1

Является ли это ошибкой с моей стороны предположить, что я могу уйти с использованием обычного const в общих функциях или это ошибка компилятора?

Предполагая, что вы говорите правду, тогда это ошибка компилятора. Вам нужно сообщить об ошибке и заблокировать использование коротких строк.

+0

Отчет отправлен: https://quality.embarcadero.com/browse/RSP-11385 (Если вы запустите образец кода, вы можете увидеть проблему). – Johan

+0

Я могу объявить перегрузку для короткой строки, что также решает проблему. – Johan

+1

И это зафиксировано в 10.1 да. – Johan