[squeak-dev] FFI (Plugin) | Question about multi-dimensional arrays (e.g., char**, int**, void*****...)

Jakob Reschke forums.jakob at resfarm.de
Mon Jun 15 09:19:21 UTC 2020


Am Mo., 15. Juni 2020 um 10:05 Uhr schrieb Marcel Taeumel <
marcel.taeumel at hpi.de>:

> > Do you think that the dimensions are always known?
>
> Yes, how would you else be able to write an FFI interface in the first
> place? If an interface says "int**" and documents "can be int***" from time
> to time, then I hope it does also give a hint on how to find that out. Is
> that even possible with C compilers?
>

Having established that the sizes are not important for the "dimensions",
ok. No, the number of effective stars cannot vary except through casting
(i. e. pretending wrong things). That question was about knowing the sizes.


> > Note that an int** is not a two-dimensional array int[x][y], so it
> might be misleading to speak of dimensions.
>
> I don't think it makes a difference from the Squeak FFI perspective.
> Pointer arithmetic for such access is currently implemented in ExternalData
> >> #at: and #at:put:. I don't think we should use more new terminology than
> necessary.
>

But we should also not use wrong or misleading terminology. Is dimension
really the word for "level of pointer nesting/number of pointer
indirections"?

As you can see in the CredEnum example, multi-dimensional arrays and
multiple nested pointers are two different things and I doubt that the FFI
can really treat them the same. For example, an int a[2][3] is just
syntactic sugar for int b[2 * 3], which you can access with a[1][2] to get
the b[1*3 + 2] element. But for an int**p array of indirections, p[1][2]
means: dereference the second pointer in my array and get the int at byte
offset 2*sizeof(int) from that. In C with int a[2][3], a[1] gives you a
pointer to the start of the second slice (like &a[0][1*3]), which makes it
look somewhat similar to an array of pointers, but that is not what it is.
There is no array of pointers to the slices at &a. It is the start of the
first slice. So I suppose the FFI has to access it differently.

Consequently you cannot correctly pass an int a[2][3] as an int**, which I
learned just yesterday. Never ever say "arrays are just pointers in C"
again. :-)

=> Don't treat arrays of pointers or nested pointers as multi-dimensional
arrays, and therefore please reconsider using the word dimension here,
unless it is well-understood and established to also describe the number of
indirections.


>
> > If you want to remember only the number of dimensions, some of my
> remarks may not apply.
>
> Of course, only the number of dimensions. The length/size has to be
> provided somewhere else. Maybe another field in my external struct. :-) Or
> maybe zero-terminatd if the library's documentation claims so. Then I have
> to count manually and store it in ExternalData >> #size. After that, I can
> enumerate the data.
>

Since there is a lot of "flexibility" here, I suppose the FFI can only help
with some of the more common patterns that you mentioned. :-) But of
course, the FFI must not presuppose that any of the patterns is used unless
that is explicitly declared in some way.

Note that eager counting can be costly. Consider a 1 GB null-terminated
char[]. ;-)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20200615/fce566ed/attachment.html>


More information about the Squeak-dev mailing list