Re: ffi type of pointer to

  • From: Justin Cormack <justin@xxxxxxxxxxxxxxxxxxxxx>
  • To: luajit@xxxxxxxxxxxxx
  • Date: Thu, 14 Jun 2012 23:11:25 +0100

On Thu, Jun 14, 2012 at 7:28 PM, Mike Pall <mike-1206@xxxxxxxxxx> wrote:

> Justin Cormack wrote:
> > On Tue, Jun 12, 2012 at 3:27 PM, Mike Pall <mike-1206@xxxxxxxxxx> wrote:
> > > Well, it's not that difficult to do for the pointer case. But I'd
> > > rather go for parameterized types, e.g.
> > >
> > >  ffi.typeof("$ *", foo_t)
> > >  ffi.typeof("struct { $ k; $ v; }[?]", foo_t, bar_t)
> > >
> > > But I'm not sure whether the complexity is really worth it.
> > >
> > Not sure about that either - never really needed anything like that in a
> C
> > context.
>
> That's because C is statically typed. C++ added templates to
> overcome this limitation (somewhat). We can certainly do better in
> Lua. ;-)
>
> Actually, it wasn't that difficult to add parameterized types to
> the FFI. The feature is now in git HEAD. No docs, yet, but you can
> already play with it:
>
> The '$' character is the marker to be replaced with parameters in
> a C type declaration:
>
> * A ctype or a cdata parameter is interpreted like an anonymous
>  typedef. You can use that to construct derived types, e.g.
>  ffi.typeof("$*", ct) is a pointer to ct, or "$[10]" is a 10
>  element array. Unlike simplistic string concatenation, this
>  works for all cases (e.g. pointers to function pointers).
>
> * A string parameter is treated like an identifier or keyword,
>  except the string is _not_ parsed again or split into words
>  (this isn't simple textual substitution). You can use that for
>  field names, function names, argument names etc.
>
>  [I'm pondering whether I should drop the keyword and type lookup
>  on the string. That would allow you to use arbitrary names for
>  fields, even when they collide with keywords or typedefs. I may
>  change that before writing the docs.]
>
> * A number parameter is treated as an integer. You can use that
>  to construct fixed size arrays. In some contexts you may prefer
>  this over VLAs. It works for multi-dimensional types, too. E.g.:
>
>    local matrix_t = ffi.typeof("uint8_t[$][$]", width, height)
>    ...
>    local m = matrix_t()
>
> Only ffi.typeof() and ffi.cdef() parse parameterized types. The
> other functions, e.g. ffi.new(), don't do that, because they
> already take other arguments (e.g. initializers). I guess it would
> be too confusing to mix two kinds of arguments.
>
> Anyway, parameterized types are a nice tool, but you'll want to
> use it sparingly!
>
> The typical scenarios where you'd use templates in C++ come to
> mind: e.g. construct a stack or a queue of an arbitrary type.
> These need to create an array of the element type, which is now
> really easy to do. [Justin's use case]
>
> Another example are derived types of anonymous structs. This
> avoids pollution of the struct namespace. [Henk's use case]
>
> I'm sure you'll come up with a lot more use cases.
>
>
Excellent. Certainly covers my use cases, will experiment with how to use
it best, and I am sure some other uses will come up...

Thanks

Justin

Other related posts: