Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does internal Lua strings store the way they do?

Tags:

c

string

struct

lua

I was wanting a simple string table that will store a bunch of constants and I thought "Hey! Lua does that, let me use some of there functions!"

This is mainly in the lstring.h/lstring.c files (I am using 5.2)

I will show the code I am curious about first. Its from lobject.h

/*
** Header for string value; string bytes follow the end of this structure
*/
typedef union TString {
  L_Umaxalign dummy;  /* ensures maximum alignment for strings */
  struct {
    CommonHeader;
    lu_byte reserved;
    unsigned int hash;
    size_t len;  /* number of characters in string */
  } tsv;
} TString;


/* get the actual string (array of bytes) from a TString */
#define getstr(ts)  cast(const char *, (ts) + 1)

/* get the actual string (array of bytes) from a Lua value */
#define svalue(o)       getstr(rawtsvalue(o))

As you see, the data is stored outside of the structure. To get the byte stream, you take the size of TString, add 1, and you got the char* pointer.

Isn't this bad coding though? Its been DRILLED into m in my C classes to make clearly defined structures. I know I might be stirring a nest here, but do you really lose that much speed/space defining a structure as header for data rather than defining a pointer value for that data?

like image 789
Paul Bruner Avatar asked Jan 23 '12 23:01

Paul Bruner


People also ask

How do strings work in Lua?

Strings in Lua are subject to automatic memory management, like all Lua objects. That means that you do not have to worry about allocation and deallocation of strings; Lua handles this for you. A string may contain a single letter or an entire book. Lua handles long strings quite efficiently.

Are Lua strings null terminated?

Strings in Lua are not zero-terminated; in consequence, they can contain arbitrary binary data and rely on an explicit length.

How do I compare strings in Lua?

In lua '==' for string will return true if contents of the strings are equal. As it was pointed out in the comments, lua strings are interned, which means that any two strings that have the same value are actually the same string.


1 Answers

The idea is probably that you allocate the header and the data in one big chunk of data instead of two:

TString *str = (TString*)malloc(sizeof(TString) + <length_of_string>);

In addition to having just one call to malloc/free, you also reduce memory fragmentation and increase memory localization.

But answering your question, yes, these kind of hacks are usually a bad practice, and should be done with extreme care. And if you do, you'll probably want to hide them under a layer of macros/inline functions.

like image 51
rodrigo Avatar answered Oct 02 '22 12:10

rodrigo