out vs. var (was: Re: [fpc-devel] Internal error in FPC 2.6.0rc1)

Michael Müller mueller_michael at alice-dsl.net
Mon Nov 28 00:49:40 CET 2011


Hi Sergei

Am 25.11.2011 um 13:49 schrieb Sergei Gorelkin:

> 25.11.2011 13:36, Michael Müller пишет:
>> Hi,
>> 
>> I tested RC1 using one of my codes and ran into an internal error. I was able to reduce the code to the following.
>> 
>> Free Pascal Compiler version 2.6.0rc1 [2011/10/15] for i386
>> Copyright (c) 1993-2011 by Florian Klaempfl and others
>> Target OS: Win32 for i386
>> Compiling InternalError.dpr
>> InternalError.dpr(21,3) Fatal: Internal error 201103063
>> Fatal: Compilation aborted
>> 
>> --- Code, start ---
>> 
>> {$IFDEF FPC}
>>   {$MODE Delphi}
>> {$ENDIF}
>> 
>> program InternalError;
>> 
>> procedure SetArray({var}out SingleArray: array of Single; const Value: Single);
>> var
>>   I: Integer;
>> begin
>>   for I := Low(SingleArray) to High(SingleArray) do
>>     SingleArray[I] := Value;
>> end;
>> 
>> var
>>   ValuesBuffer: array of Single;
>> 
>> begin
>>   SetLength(ValuesBuffer, 5);
>>   SetArray(ValuesBuffer, 5.7);
>> end.
>> 
>> --- Code, end ---
>> 
>> The error is at the beginning of SetArray() call.
>> 
> I guess this one is for me to fix.

Thanks for the fix. Hopefully it finds it way into 2.6.

>> I see that the real error is in my code since the procedure parameter has to be 'var' and not 'out' otherwise the dimension which is set outside will not reach the procedure. But the compiler shouldn't stop with an internal error. If it is changed to 'var' it compiles.
>> 
> Frankly speaking, I doubt that. 'out' in this case likely refers to elements of dynamic array, not to array itself. If it was e.g. 'array of ansistring' then all its elements should be finalized before the call, then pointer to first element and length passed to callee.

After your statement I played a little bit and it seems that you are right. When using 'out' the length of the array reaches the procedure. But what surprises me much more is that even values of the array reach the procedure. I added a loop at the beginning of the procedure that print the array before the (new) value is set and it shows the values that were set outside the procedure after SetLength(). For an array of String the elements are emptied (as you stated too). Does this mean that reference counted elements are emptied and the others not? Beside that what is than the difference between 'out' and 'var'? (I tested this also with Delphi 2009 with exact the same behaviour).
The Delphi help mentions that for 'out' parameters the referenced variable is freed (or so) when it is given to the routine (I have only a German help otherwise I would show the text here). This is exact the behaviour that I expected. So for me it sounds that even Delphi is not doing it as stated in the documentation. Where is my understanding wrong here?

Regards

Michael


More information about the fpc-devel mailing list