Array members of the dynstruct present a special problem in that the syntax to reference an array is necessarily distinct from the syntax to reference a scalar. One has a parenthesized list of subscripts at the end, the other does not. Worse, there’s no current way to avoid writing different template statements for each array with a different number of dimensions. For example, the following statements show the indirect deferred syntax for a scalar member and for a series of array members of 1, 2, and 3 dimensions:
ds.fnames$(i) ! scalar member
ds.fnames$(i)(x) ! 1-dimension array member
ds.fnames$(i)(x,y) ! 2-dimension array member
ds.fnames$(i)(x,y,z) ! 3-dimension array member
The compiler has no way to enforce agreement between the subscripts specified at compile time and the number actually needed for the target member at run-time, because it doesn’t know which dynstruct member fnames$(i) will evaluate to. The runtime system can detect the most common error, where you use the first syntax above for an array member, i.e. you forget to supply any subscripts for the array member. That will produce an undefined member error; see Dynstruct Error Handling. But it cannot detect the case where the target array needs 3 subscripts, but you only supplied 2, or vice versa. That might cause a stack overflow or underflow, but it might just cause another part of the current expression (waiting its turn on the stack) to be misused as an array subscript, which in turn will almost certainly lead to another runtime error like illegal syntax code or undefined function.
One take-away is to avoid using arrays in dynstructs. If that’s not possible, the other is that is you must then be careful to add logic like the following to detect the various array cases and to use the appropriate template statements depending on the dimensionality of each array member.
! sample retrieval/display using indirect deferred syntax
! (with logic to avoid printing members of type X or with sub-members,
! and logic to handle array members)
for i = 1 to fields
if (flddefs(i).vartyp and VARTYP_MASK) = VARTYP_X then
repeat ! skip X vars
elseif (i < fields) and flddefs(i+1).pos = flddefs(i).pos then
repeat ! skip vars with sub-layouts
elseif flddefs(i).subs = 0 then ! scalar member
? dstest.@fnames$(i) ! print only non-X, non-multilevel
else
switch flddefs(i).subs
case 1 ! 1 dimension array
for x = 1 to flddefs(i).subext(1)
? dstest.@fnames$(i)(x)
next x
exit
case 2 ! 2 dimension array
for x = 1 to flddefs(i).subext(1)
for y = 1 to flddefs(i).subext(2)
? dstest.@fnames$(i)(x,y)
next y
next x
exit
case 3 ! 3 dimension array
for x = 1 to flddefs(i).subext(1)
for y = 1 to flddefs(i).subext(2)
for z = 1 to flddefs(i).subext(3)
? dstest.@fnames$(i)(x,y,z)
next z
next y
next x
exit
endswitch
endif
next i