CRobin писал(а):Можно немного подробнее об этом? Всегда считал что разница в данном примере сугубо синтаксическая.
Я тоже, но...
- Код: Выделить всё
{$if fpc_fullversion < 30000} {$error} {$endif}
{$mode objfpc} {$longstrings on} {$coperators on}
type
PAnsiRec = ^TAnsiRec;
TAnsiRec = record
CPAwareShit: record
case byte of
0: (CodePage: TSystemCodePage; ElementSize: Word);
1: (Padding: SizeInt);
end;
ref: SizeInt;
len: SizeInt;
end;
function StringRefCount(const s: string): SizeInt;
begin
if Assigned(pointer(s)) then
result := (PAnsiRec(s) - 1)^.ref
else
result := -1;
end;
procedure VarParam(var s: string);
begin
repeat readln(s); until s <> '';
writeln('refcount inside VarParam: ', StringRefCount(s));
end;
function ReturnAsResult: string;
begin
repeat readln(result); until result <> '';
writeln('refcount inside ReturnAsResult: ', StringRefCount(result));
end;
var
s: string;
begin
s := ReturnAsResult;
writeln('refcount outside ReturnAsResult = ', StringRefCount(s));
VarParam(s);
writeln('refcount outside VarParam = ', StringRefCount(s));
end.
У меня выводит
- Код: Выделить всё
refcount outside ReturnAsResult = 2
refcount outside VarParam = 1
, что означает, что в случае с result строка сохраняется, с атомарным увеличением счётчика ссылок, во временную переменную. Думаю, это багофича для перестраховки от случая, когда функция внутри себя обращается к той же переменной, которой присвоила (бы) результат. Так себе перестраховка: существующая в том же FPC {$OPTIMIZATION UNCERTAIN}, например, не считает зазорным изредка генерировать невалидный (точнее, неэквивалентный) код для случаев, когда указатель (в т. ч. var-параметр) ссылается на переменную.