Re: what exactly happens with string casts?

  • From: Mike Pall <mike-1205@xxxxxxxxxx>
  • To: luajit@xxxxxxxxxxxxx
  • Date: Wed, 16 May 2012 14:14:51 +0200

Arran Cudbard-Bell wrote:
> On 16 May 2012, at 12:45, Mike Pall wrote:
> > A cast NEVER makes a copy of anything. It converts one type of
> > pointer to another. And a Lua string is implicitly treated like a
> > "const char *" pointer to its first character.
> 
> This is pretty much the same as the implicit operation that
> occurs when you pass a Lua string to an FFI function that
> requires a char *? Or does the string get copied to some
> intermediary buffer?

["const char *", but not "char *".]

The implicit Lua string -> "const char *" conversion works the
same in all contexts. Whether that's a C function argument or a
struct field you're storing to, etc.

Aggregates are never copied implicitly.

[
E.g. if you reference an element in an array of structs, no copy
is performed! You get a reference (C++ '&') to the start of the
struct, which behaves exactly like a struct object (unlike a
pointer to a struct, as we've recently discussed).
]

> Is there any way to avoid interning the string, but still pass
> it as arguments to standard Lua functions (i'm guessing no)? For
> example using the build in io.write functions to write out the
> contents of a char array?

Well, no. The problem is that all standard library functions that
consume a string argument only expect a single argument. But for
cdata you'd need to pass both a pointer and a length argument.

But since you're concerned about performance, you might as well
call the C functions fwrite() or even write()/WriteFile() and
pass the buffer and length.

[
I've tried to eliminate the temporary string interning for JIT-
compiled code, e.g. io.write(ffi.string(p, len)). But it'd only
work where the string interning and the C call are very close
together, i.e. not in all contexts. So I didn't bother.

It's hard to derive that the contents of 'p' aren't modified by
unrelated C calls, e.g. the fwrite() itself. And thinking about
it, the fwrite() may write to a memory buffer (some C libs have
this feature) and p might be a pointer to that buffer. Ugh.
]

--Mike

Other related posts: