<div id="__MailbirdStyleContent" style="font-size: 10pt;font-family: Arial;color: #000000">Hi Jakob.<div class="mb_sig"></div>
                                        
                                        <div><br></div><div>> <span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">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. :-)</span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px"><br></span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">Got it! :-) A </span><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">two-dimensional array (i.e. int[][]) occupies a single contiguous block of memory while an array of pointers (i.e. int**) as an extra level of indirection and is likely to point to multiple (contiguous) memory blocks, one for each "entry" or "array" (here: int* or int[]). </span><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">Hmm... only for int* vs int[] it does not matter. Hmm...</span></div><div><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px"><br></span></div><div><div style="font-size: 13.3333px"><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">> </span><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">multi-dimensional arrays and multiple nested pointers are two different things and I doubt that the FFI can really treat them the same.</span></div><div style="font-size: 13.3333px"><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px"><br></span></div><div style="font-size: 13.3333px"><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">In an FFI call, for example, an IntegerArray can be coerced to int*, which includes n-dimensional arrays because that memory is contiguous anyway. If a function expects int** as one argument ... you may try to give a pointer address via ByteArray? I am not sure how to express "&ptr" in Squeak FFI having an ExternalAddress at hand.  ExternalAddress class >> #allocate: does already malloc(). Not sure how to create pointer "in" the heap that is not yet defined, i.e. "int *ptr;"</span></div></div><div style="font-size: 13.3333px"><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px"><br></span></div><div style="font-size: 13.3333px"><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">Anyway, a struct field with "int **" is more fun to think about for now. :-) Because it does not involve an FFI call and argument coercing. And comparing that to "int[][]".</span></div><div style="font-size: 13.3333px"><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px"><br></span></div><div style="font-size: 13.3333px"><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px">What about encoding not only the ... "levels of indirection" for a pointer but also whether it is an array (= contiguous memory) such as int[][] or has pointers to follow in between such as int**?</span></div><div style="font-size: 13.3333px"><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px"><br></span></div><div style="font-size: 13.3333px"><img id="cf6d71db-56fd-49c6-9fe9-66c8f6aa7204" src="cid:d6265c53-a2d5-470a-9655-c2904febe985" width="auto"></img><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px"><br></span></div><div style="font-size: 13.3333px"><br></div><div style="font-size: 13.3333px">Best,</div><div style="font-size: 13.3333px">Marcel</div><div style="font-size: 13.3333px"><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px"><br></span></div><div style="font-size: 13.3333px"><span style="font-family: Arial, Helvetica, sans-serif;font-size: 13px"><br></span></div><blockquote class="history_container" type="cite" style="border-left-style: solid;border-width: 1px;margin-top: 20px;margin-left: 0px;padding-left: 10px;min-width: 500px">
                        <p style="color: #AAAAAA; margin-top: 10px;">Am 15.06.2020 11:19:43 schrieb Jakob Reschke <forums.jakob@resfarm.de>:</p><div style="font-family:Arial,Helvetica,sans-serif">
<div dir="ltr"><div dir="ltr">Am Mo., 15. Juni 2020 um 10:05 Uhr schrieb Marcel Taeumel <<a href="mailto:marcel.taeumel@hpi.de">marcel.taeumel@hpi.de</a>>:<br></div><div class="gmail_quote"><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex;border-left: 1px solid rgb(204,204,204);padding-left: 1ex;min-width: 500px"><div id="gmail-m_8193020684363998865__MailbirdStyleContent" style="font-size: 10pt;font-family: Arial;color: rgb(0,0,0)"><div>> <span style="font-family: Arial,Helvetica,sans-serif;font-size: 13px">Do you think that the dimensions are always known?</span></div><div><span style="font-family: Arial,Helvetica,sans-serif;font-size: 13px"><br></span></div><div><span style="font-family: Arial,Helvetica,sans-serif;font-size: 13px">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?</span></div></div></blockquote><div><br></div><div>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.</div><div> </div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex;border-left: 1px solid rgb(204,204,204);padding-left: 1ex;min-width: 500px"><div id="gmail-m_8193020684363998865__MailbirdStyleContent" style="font-size: 10pt;font-family: Arial;color: rgb(0,0,0)"><div><span style="font-size: 10pt">> </span><span style="font-family: Arial,Helvetica,sans-serif;font-size: 13px">Note that an int** is not a two-dimensional array int[x][y], so it might be misleading to speak of dimensions.</span><br></div><div><span style="font-family: Arial,Helvetica,sans-serif;font-size: 13px"><br></span></div><div><span style="font-family: Arial,Helvetica,sans-serif;font-size: 13px">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.</span></div></div></blockquote><div><br></div><div>But we should also not use wrong or misleading terminology. Is dimension really the word for "level of pointer nesting/number of pointer indirections"?</div><div><br></div><div>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.</div><div><br></div><div>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. :-)</div><div><br></div><div>=> 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.</div><div> </div><blockquote class="gmail_quote" style="margin: 0px 0px 0px 0.8ex;border-left: 1px solid rgb(204,204,204);padding-left: 1ex;min-width: 500px"><div id="gmail-m_8193020684363998865__MailbirdStyleContent" style="font-size: 10pt;font-family: Arial;color: rgb(0,0,0)"><div><span style="font-family: Arial,Helvetica,sans-serif;font-size: 13px"><br></span></div><div><span style="font-family: Arial,Helvetica,sans-serif;font-size: 13px">> </span><span style="font-family: Arial,Helvetica,sans-serif;font-size: 13px">If you want to remember only the number of dimensions, some of my remarks may not apply.</span></div><div><span style="font-family: Arial,Helvetica,sans-serif;font-size: 13px"><br></span></div><div><span style="font-family: Arial,Helvetica,sans-serif;font-size: 13px">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.</span></div></div></blockquote><div><br></div><div>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.</div><div><br></div><div>Note that eager counting can be costly. Consider a 1 GB null-terminated char[]. ;-)</div></div></div>
</div></blockquote></div>