[fpc-pascal] Re: Pointer to first dynamic array element (was: Re: Correct use of var in function calls?)

Bo Berglund bo.berglund at gmail.com
Sat Feb 5 16:05:19 CET 2011


On Sat, 5 Feb 2011 12:47:53 +0100, Michael Müller
<mueller_michael at alice-dsl.net> wrote:

>Hi Bo!
>
>Am 03.02.2011 um 22:53 schrieb Bo Berglund:
>
>> function TSSCommBuf.Read(var Data: TByteArr): boolean; // <== ???
>> begin
>>  Result := Read(@Data, SizeOf(Data)) = SizeOf(Data);
>> end;
>
>When using dynamic arrays @Data will not be the address of the first 
>array element which is usually what you want in combination with Read(). 
>Since the dynamic array stores its length at the beginning with @Data 
>you would overwrite the length value too.
>
>So you have to use @Data[0]. Since this works also for static arrays 
>you can / should do it always this way. This makes it also much easier 
>to switch later from a static to a dynamic array.

I already did this in my *real* buffer class where I have 7 overloaded
Read methods for different datatypes. Needed this for string and
TByteArr.
Examples:

function TSSCommBuf.Read(var Data: Cardinal): boolean;
begin
  Result := Read(@Data, SizeOf(Data)) = SizeOf(Data);
end;

function TSSCommBuf.Read(Data: TByteArr): boolean;
begin
  Result := Read(@Data[0], Length(Data)) = Length(Data);
end;

function TSSCommBuf.Read(var Data: string; const Count: Cardinal):
boolean;
begin
  Result := Read(@Data[1], Count) = Count;
end;

All call the "real" Read method:

function TSSCommBuf.Read(Dest: Pointer; Count: Cardinal): Cardinal;
var
  num: Cardinal;
  Src: Pointer;
begin
  num := FWriteIndex - FReadIndex;  //Remaining data bytes in buffer
  if num >= Count then
    num := Count;
  if num > 0 then
  begin
    Src := @FBuf[FReadIndex];
    Move(Src^, Dest^, num);
    FReadIndex := FReadIndex + num;
  end;
  Result := num;
end;

>A further hint for another example from you: When looping through 
>the array use 
>
>for I := Low(Data) to High(Data)
>
>instead of Len := Length(Data) and looping to Len - 1. Let the 
>compiler do defining this local variable and the calculation.
>

I know, but I use Move() for performance reasons in my real buffer
class. The other loops were only to check how the references were
working.


Bo Berglund




More information about the fpc-pascal mailing list