[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