An recent coding error revealed that it is possible to pass a bounded array
to a dynamic array. Here is how.


type
   TIntArray = array of integer;
   PIntArray = ^TIntArray;


(* helper, it displays the ref counter of a dynamic array *)
procedure DisplayRefCount(A: TIntArray);
var
   P : Pointer;
begin
   P := A;

   P := Pointer(Integer(P) - 4);
   ShowMessage(IntToStr(PInteger(P)^));
end;


(* the first pair of the test: uses a valid syntax *)
procedure PassArray(pA: PIntArray);
var
   B : TIntArray;
begin
   B := pA^;

   ShowMessage(IntToStr(B[1]));

   DisplayRefCount(B);
end;


procedure Test;
var
   A : TIntArray;
begin
   SetLength(A, 2);

   A[0] := 22;
   A[1] := 33;

   PassArray(@A);
end;


(* the second pair of the test:  assigns the address of a dynamic array
    to a dynamic array variable. I believe that souldn't work.
    But it works. Merely. The returned ref count is wrong, of cource,
    because while pA is a pointer to a dynamic array it is passed the
    address of a typed array.

    It probably works because a dynamic array is implemented as a pointer to a 
typed array
    and because it is valid to pass an un-typed pointer expression to a dynamic 
array
    (in fact it is valid to pass an un-typed pointer to any typed pointer)...
*)
procedure PassArray2(pA: PIntArray);
var
   B  : TIntArray;
begin
   B := @(pA^);

   ShowMessage(IntToStr(B[1]));

   DisplayRefCount(B);
end;


(* I have the type address ($TYPEDADDRESS) compiler directive as  {$T-}, the 
default
    setting, wich makes the @ operator to return an un-typed pointer.
    The fact that it is valid to pass an un-typed pointer to a typed pointer,
    is the source of the error

    var
      pI : PInteger;
      P  : Pointer;
    begin
      PI := P;
    end;
*)
procedure Test2;
var
   A : array[0..1] of integer; // now, try a bounded array
begin
   A[0] := 22;
   A[1] := 33;

   PassArray2(@A);  // here lies the root of the problem
end;


(* and the best of all: putting the code of the second test
    in a single function, makes it to raise an AV *)
procedure Test3;
var
   A  : array[0..1] of integer;
   B  : TIntArray;
   pA : PIntArray;
begin
   A[0] := 22;
   A[1] := 33;

   pA := @A;

   B := @(pA^);

   ShowMessage(IntToStr(B[1]));

   DisplayRefCount(B);
end;

-- 
Regards
Theo

------------------------
Theo Bebekis
Thessaloniki, Greece
------------------------
Greek_Delphi_Prog : a Delphi Programming mailing list in Greek at
    http://groups.yahoo.com/group/Greek_Delphi_Prog

CSharpDotNetGreek : A C# and .Net mailing list in Greek language at
    http://groups.yahoo.com/group/CSharpDotNetGreek

atla_custom : a Unisoft Atlantis Customization mailing list at
    http://groups.yahoo.com/group/atla_custom
------------------------

------------------------------------

-----------------------------------------------------
Home page: http://groups.yahoo.com/group/delphi-en/
To unsubscribe: [email protected]! Groups Links

<*> To visit your group on the web, go to:
    http://groups.yahoo.com/group/delphi-en/

<*> Your email settings:
    Individual Email | Traditional

<*> To change settings online go to:
    http://groups.yahoo.com/group/delphi-en/join
    (Yahoo! ID required)

<*> To change settings via email:
    mailto:[email protected] 
    mailto:[email protected]

<*> To unsubscribe from this group, send an email to:
    [email protected]

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.com/info/terms/

Reply via email to