Re: [fpc-pascal] Re: Correct use of var in function calls?
On Sun, 6 Feb 2011, Florian Klämpfl wrote: Am 06.02.2011 18:53, schrieb Bo Berglund: So in summary: If the called method changes the length of teh dynamic array it must be passed as a var, otherwise the length change will be lost when exiting the method. I'd even propose that one uses var as soon as he plans to change the array. It makes the code easier to understand. Indeed. It indicates that you expect the array to be changed. Michael.___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Re: Correct use of var in function calls?
Am 06.02.2011 18:53, schrieb Bo Berglund: So in summary: If the called method changes the length of teh dynamic array it must be passed as a var, otherwise the length change will be lost when exiting the method. I'd even propose that one uses var as soon as he plans to change the array. It makes the code easier to understand. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Re: Correct use of var in function calls?
On Sat, 5 Feb 2011, Bo Berglund wrote: On Fri, 4 Feb 2011 19:10:33 +0100, Jonas Maebe jonas.ma...@elis.ugent.be wrote: On 04 Feb 2011, at 16:25, Bo Berglund wrote: OK, what will happen if I have a declaration like this: function TSSCommBuf.Read(var Data: TByteArr): boolean; as opposed to function TSSCommBuf.Read(Data: TByteArr): boolean; Will they be equivalent or will there be an extra layer of pointer?? They are different. And it's not just an extra layer of pointer, both declarations allow you to do different things. In the second case, you make a copy of the dynamic array and hence its reference count is increased. In the first case, you pass in the original dynamic array in, and hence a) no increase in reference count b) if you do e.g. data:=nil, then the variable that was passed in will set to nil and the reference count of the dynamic array will decrease (and if it becomes zeroed, it will be freed) I made a test in Delphi7 as follows: type TByteArr = array of byte; ... function TForm1.FillArray(Arr: TByteArr): boolean; var i, Len: integer; begin Len := Length(Arr); for i := 0 to Len-1 do Arr[i] := i mod 256; end; procedure TForm1.Button1Click(Sender: TObject); var Len: Cardinal; i, s1, s2: integer; FLocal: TByteArr; P1, P2: Pointer; begin Len := speSize.Value; SetLength(FBuf, Len); SetLength(FLocal, Len); FillArray(FLocal); s1 := Length(FBuf); When I reach this position the debugger shows that FLocal contains the data (0,1,2,3,4,5,6.) which were entered by the FillArray function, which seems to contradict your statement that a *copy* of the array is made for use in the called function. I then tried two other variations of the same function: function TForm1.FillArray(var Arr: TByteArr): boolean; function TForm1.FillArray(const Arr: TByteArr): boolean; In all these cases the data entered into the array in the FillArray function remain when the call returns. THe array contains (0,0,0,0...) before the calls and (0,1,2,3,4,5...) after the calls. To me it looks like the dynamic array is *always* passed by *reference* to the FillArray function in Delphi 7 No. Someone misunderstands the concept of dynamic array here. A dynamic array is a pointer to an array in memory. So when passing a dynamic array to a function, you are, in fact, passing a pointer. So is there a difference here between Delphi7 and FPC? No. Test the following program: Var A,B : Array of byte; I : integer; begin SetLength(A,10); For I:=0 to 9 do A[I]:=I+1; B:=A; // A pointer is copied. B[5]:=33; Writeln(A[5]); end. This will write 33. All this is explained in the Delphi (and FPC) documentation. Michael. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Re: Correct use of var in function calls?
On Sat, 5 Feb 2011, Bo Berglund wrote: On Sat, 5 Feb 2011 09:24:44 +0100 (CET), michael.vancann...@wisa.be wrote: No. Someone misunderstands the concept of dynamic array here. A dynamic array is a pointer to an array in memory. So when passing a dynamic array to a function, you are, in fact, passing a pointer. So is there a difference here between Delphi7 and FPC? No. So in effect it means that all of these calls are exactly the same: FillArr(const Arr: TByteArr) FillArr(var Arr: TByteArr) FillArr(Arr: TByteArr) At least as long as the FillArr function does not attempt to change the ponter itself like this: Arr := SomeOtherArr; Indeed. In which case I guess that the only version that will carry this back to the caller is the var version? Yes. But that is not what I am doing at all, so I can stick with a simple: FillArr(Arr: TByteArr) and be sure that I will not get back a different array, but instead get my array filled as requested... It should, yes. Michael. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Re: Correct use of var in function calls?
Am 05.02.2011 10:46, schrieb Bo Berglund: But that is not what I am doing at all, so I can stick with a simple: FillArr(Arr: TByteArr) and be sure that I will not get back a different array, but instead get my array filled as requested... As soon as you call SetLength, this will break havoc. Then a deep copy is generated and it gets ref. count of 1 and it is destroyed at callee exit. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Re: Correct use of var in function calls?
On 04 Feb 2011, at 16:25, Bo Berglund wrote: OK, what will happen if I have a declaration like this: function TSSCommBuf.Read(var Data: TByteArr): boolean; as opposed to function TSSCommBuf.Read(Data: TByteArr): boolean; Will they be equivalent or will there be an extra layer of pointer?? They are different. And it's not just an extra layer of pointer, both declarations allow you to do different things. In the second case, you make a copy of the dynamic array and hence its reference count is increased. In the first case, you pass in the original dynamic array in, and hence a) no increase in reference count b) if you do e.g. data:=nil, then the variable that was passed in will set to nil and the reference count of the dynamic array will decrease (and if it becomes zeroed, it will be freed) Jonas___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal