The "Pointer To" data type isn't a key feature of (GFA-)BASIC. A BASIC programmer should not be bothered with pointers, at least that is the consensus. If you like to know more about pointers in GFA-BASIC check out ByRef arguments are Pointer To variables.
Introduction
One of the many variants of "Pointer To" I never considered; a declaration of an array of type "As Pointer To type" . For example, what does this do?
Dim a(1) As Pointer Large
It turns out that (with Option Base 0) the array contains two elements (0,1) of int32 data type. Two Longs are allocated and not two Large variables (int64). The same is true of all other types. Due to the Pointer keyword the elements are only 32-bit wide and are initialized to Null.
Code
This time I don't present a smoking explanation but sample code only. It contains 3 examples of 3 different array types, but they are all of Pointer To. See what happens.
' Essentially, it is an array of 32-bit integers ' to hold addresses of memory locations. ' The array's data type determines how to use ' the address stored in the elements. ' Example 1 - Array as a Pointer To Large Dim a(1) As Pointer Large Trace ArraySize(a()) ' 8 bytes, thus 2 * 4 bytes ' Assign memory locations to the elements: Dim il As Large = 9, jl As Large = 10 Pointer(a(0)) = V:il ' set array-elem to address of i Pointer(a(1)) = V:jl ' Due to "As Pointer To Large" GFA performs ' an indirect access using the addresses stored in ' array elements. It does NOT directly return the ' values stored in a(0) or a(1) (which are memory locations). Trace a(0) ' = 9 Trace a(1) ' = 10 ' How does GFA do this? ' Well, let us see what is actually stored in a(0) and a(1). ' We use ArrayAddr() to obtain the addresses of the array elements and then Lpeek the address stored there and then use Large{adr} to obtain the value. Dim adr As Int adr = Int{ArrayAddr(a()) + 0} ' a(0) Trace Large{adr} ' = 9 adr = Int{ArrayAddr(a()) + 4} ' a(1) Trace Large{adr} ' = 10 ' Example 2 - Array as a Pointer To String ' Again an array of 32-bit integers, but now they must ' be set to point to the string's descriptor. Dim s(1) As Pointer String, st As String = "Hello" Trace ArraySize(s()) ' still 8 bytes Pointer(s(0)) = *st ' assign string descriptors Pointer(s(1)) = *st ' assign string descriptors ' See how GFA correctly uses the addresses to ' obtain the strings: Trace s(0) ' = Hello Trace s(1) ' = Hello ' Internally handled as: Trace Char{{{ArrayAddr(s()) + 0 }}} Trace Char{{{ArrayAddr(s()) + 4 }}} ' Example 3 - Array as a Pointer To UDT ' Again an array of 32-bit integers, but now they must ' be set to point to instances of ArrayDesc type. Dim ad(1) As Pointer ArrayDesc Trace ArraySize(ad()) ' still 8 bytes ' Use ArrayDesc of previously declared arrays Pointer(ad(0)) = *a() ' assign addr of ArrayDesc a() Pointer(ad(1)) = *s() ' assign addr of ArrayDesc s() ' See how GFA correctly uses the addresses Trace ad(0).ptype ' 37 ($24 + $1) Trace ad(1).ptype ' 73 ($48 + $1) ' Internally handled as: Trace Int{{ArrayAddr(ad()) + 0 } + 4} Trace Int{{ArrayAddr(ad()) + 4 } + 4} Type ArrayDesc -Int Magic ' 4 Byte ASCII -Int ptype ' vtType -Int size ' size of the datatype -Int dimCnt ' number of dimensions -Int dimCnt2 ' Erase and $ArrayChk -Int paddr ' ArrayAddr() -Int corr ' correction value -Int paddrCorr ' void*addrCorr; -Int anzElem ' number of elements -Int sizeArr ' size in bytes ArraySize() -Int Idx(3) '[3][1]; //Open Array EndType
Note - A declaration of an array creates an array descriptor which the array variable references. Operations on the variable are performed using the content of the descriptor. This is not about the array descriptor, but it illustrates what is allocated with Dim. The UDT ArrayDesc is used as an example for an array of Pointer To UDT.
Conclusion
GFA-BASIC 32 returns the content of array elements correctly, but this only works when the array elements are assigned the addresses of memory locations that need to be read using the arrays data type.
No comments:
Post a Comment