[fpc-devel] Managed Types, Undefined Bhaviour

Ondrej Pokorny lazarus at kluug.net
Sat Jul 7 10:37:57 CEST 2018


On 29.06.2018 17:57, Stefan Glienke wrote:
> Change the code to following:
>
> type
>    TFoo = class
>      A, B: Vector;
>    end;
>
> procedure Main;
> var
>    foo: TFoo;
> begin
>    foo := TFoo.Create;
>    foo.A := DoSomething(3);
>    foo.A[0] := 42;
>    foo.B := DoSomething(4);
>    Writeln(foo.B[0]);
> end;
>
>
> Now we are back to using temp variables (both Delphi and FPC do) but FPC again reuses its temp variable for A and B while Delphi uses different ones. Now for some integer this might not be a big issue but imagine you have something else in these arrays (for example any managed type like an interface).
> Not having properly cleared B because it still uses the temporary content from A might cause some issues.

Change the code to the following:

program Project1;
{$APPTYPE CONSOLE}
type
   Vector = array of integer;
   TFoo = class
     A, B: Vector;
   end;
function DoSomething (len: Integer): Vector;
begin
   SetLength(Result, len);
end;
var
   foo: TFoo;
   I: Integer;
begin
   foo := TFoo.Create;
   for I := 0 to 1 do
   begin
     foo.A := foo.A + DoSomething(3);
     foo.A[0] := 42;
   end;
   WriteLn(foo.A[3]); // << writes 42 even in Delphi !!!
   Readln;
end.

Delphi 10 outputs "42"! Yes, and this is not a bug!

Result is not guaranteed to be cleared. Not in Delphi, nor in FPC.

Yes, you showed us one code example where Delphi clears the result and where FPC does not but that's all. Delphi behavior can change any time in the future as it has already been in other cases of undocumented behavior. So your example can stop working in future Delphi versions, if e.g. some optimizations will be added.

Ondrej




More information about the fpc-devel mailing list