~sircmpwn/hare-users

3 3

question how to create and interact with C's array of pointers

Details
Message ID
<CADa827GB+8HDBUoDTX0gs3Cq_xxKJHqDFxx3y9skiouL=_5Q0g@mail.gmail.com>
DKIM signature
pass
Download raw message
how to iterate over c array? and is it possible to initialize C's
array of pointer in Hare?
is it possible to cast **opaque to [*]*opoaque and iterate through it?
Details
Message ID
<ZgZzKyZvp9r78F8K@fluorine>
In-Reply-To
<CADa827GB+8HDBUoDTX0gs3Cq_xxKJHqDFxx3y9skiouL=_5Q0g@mail.gmail.com> (view parent)
DKIM signature
pass
Download raw message
Quoth Abdul Wahab:
>how to iterate over c array? and is it possible to initialize C's
>array of pointer in Hare?

In C, when you have an array of pointers, it looks like this: 
[text diagrams]

	int i, *a[5] = {&i, &i, &i, &i, &i};

	   +----+----+----+----+----+
	a: | &i | &i | &i | &i | &i |
	   +----+----+----+----+----+

Perhaps because not every part of the code base knows the size of 
the array, or perhaps because the array is allocated, you might 
want to pass not the array itself around (which is impossible) or 
a pointer to it (which would be possible), but a pointer to its 
first element.

	extern void f(int *[], size_t); /* here, syntactic sugar for int ** */
	int **p = a;
	f(p, sizeof a / sizeof a[0]);

	   +----+----+----+----+----+
	a: | &i | &i | &i | &i | &i |
	   +----+----+----+----+----+
	     ↑
	     p

In Hare, you can start the same way, with an array of fix size.

	let i = 42;
	let a: [5]*int = [&i, &i, &i, &i, &i];

	   +----+----+----+----+----+
	a: | &i | &i | &i | &i | &i |
	   +----+----+----+----+----+

But since Hare doesn’t give you pointer arithmetic, it’s  vastly 
less useful to have a pointer to the first element of an array.  
Where you’d pass a pointer to the first element together with the 
size in C, you might pass a slice in Hare, acting as a kind of 
pointer to a whole sub-array.

	fn f([]*int) void;

	let s: []*int = a;
	f(s);

	   +----+----+----+----+----+
	a: | &i | &i | &i | &i | &i |
	   +----+----+----+----+----+
	     ↑
	   s.data

	    s.length, s.capacity = 5
	   |←---+----+----+----+---→|

If you don’t want to use a slice, because you’re talking to 
C perhaps, you can do something similar to what you’d do in C.  
Again, as Hare doesn’t provide pointer arithmetic, passing 
a pointer to the first element (**int) around is less useful, but 
if your C function wants that, it’s possible.  What would be 
better, though, is indeed a pointer to an array of unspecified 
size:

	fn g(*[*]*int, size) void;
	let p: *[*]*int = &a;
	g(p, len(a));

	   +----+----+----+----+----+
	a: | &i | &i | &i | &i | &i |
	   +----+----+----+----+----+

	   `----------------→
	         ↑
	         p

The semantic here is that p points to the whole array; it just 
doesn’t know the whole size.

>is it possible to cast **opaque to [*]*opoaque and iterate through it?

Not quite: You can’t directly work with these arrays of 
unspecified size.  How much memory does it use?  If you copied it, 
how large would the copy be?  What you can do is have a pointer to 
them.

	// Hare
	export @symbol("sum") fn sum(p: *int, n: size) int = {
		let a = p: *[*]int;
		let res = 0;
		for (let i = 0z; i < n; i += 1) {
			res += a[i];
		};
		return res;
	};

	/* C */
	extern int sum(int *, size_t);
	int a[] = {1, 2, 3, 4, 5};
	int s = sum(a, sizeof a / sizeof a[0]);

I hope this gives you some ideas and/or intuition.
Details
Message ID
<CADa827F-qzXsRPt5uqmAv_LRD2zjT3arUJAaqCmcRrJCMSikSA@mail.gmail.com>
In-Reply-To
<ZgZzKyZvp9r78F8K@fluorine> (view parent)
DKIM signature
pass
Download raw message
Hi, I tried to write a wrapper for a C library, a struct with one of
its field being `**opaque`.
Based on the doc, it's an array of pointers with each pointer being an
array of pixels.

I can't cast it to `[*]*Surface`.
struct `types::slice` also does not work.
the length is not known at compile time.
I've also thought about allocating a `[]*opaque`. but I don't know how
to copy the pointers into it. since i can't iterate through a
`**opaque`

B


Pada Jum, 29 Mar 2024 pukul 14.52 Lennart Jablonka <humm@ljabl.com> menulis:
>
> Quoth Abdul Wahab:
> >how to iterate over c array? and is it possible to initialize C's
> >array of pointer in Hare?
>
> In C, when you have an array of pointers, it looks like this:
> [text diagrams]
>
>         int i, *a[5] = {&i, &i, &i, &i, &i};
>
>            +----+----+----+----+----+
>         a: | &i | &i | &i | &i | &i |
>            +----+----+----+----+----+
>
> Perhaps because not every part of the code base knows the size of
> the array, or perhaps because the array is allocated, you might
> want to pass not the array itself around (which is impossible) or
> a pointer to it (which would be possible), but a pointer to its
> first element.
>
>         extern void f(int *[], size_t); /* here, syntactic sugar for int ** */
>         int **p = a;
>         f(p, sizeof a / sizeof a[0]);
>
>            +----+----+----+----+----+
>         a: | &i | &i | &i | &i | &i |
>            +----+----+----+----+----+
>              ↑
>              p
>
> In Hare, you can start the same way, with an array of fix size.
>
>         let i = 42;
>         let a: [5]*int = [&i, &i, &i, &i, &i];
>
>            +----+----+----+----+----+
>         a: | &i | &i | &i | &i | &i |
>            +----+----+----+----+----+
>
> But since Hare doesn’t give you pointer arithmetic, it’s  vastly
> less useful to have a pointer to the first element of an array.
> Where you’d pass a pointer to the first element together with the
> size in C, you might pass a slice in Hare, acting as a kind of
> pointer to a whole sub-array.
>
>         fn f([]*int) void;
>
>         let s: []*int = a;
>         f(s);
>
>            +----+----+----+----+----+
>         a: | &i | &i | &i | &i | &i |
>            +----+----+----+----+----+
>              ↑
>            s.data
>
>             s.length, s.capacity = 5
>            |←---+----+----+----+---→|
>
> If you don’t want to use a slice, because you’re talking to
> C perhaps, you can do something similar to what you’d do in C.
> Again, as Hare doesn’t provide pointer arithmetic, passing
> a pointer to the first element (**int) around is less useful, but
> if your C function wants that, it’s possible.  What would be
> better, though, is indeed a pointer to an array of unspecified
> size:
>
>         fn g(*[*]*int, size) void;
>         let p: *[*]*int = &a;
>         g(p, len(a));
>
>            +----+----+----+----+----+
>         a: | &i | &i | &i | &i | &i |
>            +----+----+----+----+----+
>
>            `----------------→
>                  ↑
>                  p
>
> The semantic here is that p points to the whole array; it just
> doesn’t know the whole size.
>
> >is it possible to cast **opaque to [*]*opoaque and iterate through it?
>
> Not quite: You can’t directly work with these arrays of
> unspecified size.  How much memory does it use?  If you copied it,
> how large would the copy be?  What you can do is have a pointer to
> them.
>
>         // Hare
>         export @symbol("sum") fn sum(p: *int, n: size) int = {
>                 let a = p: *[*]int;
>                 let res = 0;
>                 for (let i = 0z; i < n; i += 1) {
>                         res += a[i];
>                 };
>                 return res;
>         };
>
>         /* C */
>         extern int sum(int *, size_t);
>         int a[] = {1, 2, 3, 4, 5};
>         int s = sum(a, sizeof a / sizeof a[0]);
>
> I hope this gives you some ideas and/or intuition.
Details
Message ID
<D066XWFROTUK.1X2TPB1Q2MMXD@cmpwn.com>
In-Reply-To
<CADa827F-qzXsRPt5uqmAv_LRD2zjT3arUJAaqCmcRrJCMSikSA@mail.gmail.com> (view parent)
DKIM signature
pass
Download raw message
Can you share the prototype for the C function you are trying to use?
Reply to thread Export thread (mbox)