Lua Faq

lua-users home
wiki

This page contains unofficial answers to frequently asked questions about Lua. It is maintained by the Lua community. Questions covered in the official Lua FAQ [1] will not be answered here.

If you have a question about Lua, and haven't had any luck finding the answer in available resources, such as the Lua documentation and this FAQ, the best thing to do is post it to lua-l [2]. That will allow the most people to see it in the shortest time, and you are likely to get a timely response. If some experienced person on the list feels that your question is frequently asked, they may add an entry to this FAQ.

Also see this standalone FAQ [3].

FAQ Topics

Lua Programming

How is conditional compilation done in Lua?

Lua does not include a preprocessor, so how does one do conditional compilation? First, what is the purpose of conditional compilation? Often it is used only to control the definition of functions or variables at the global scope. In Lua this can be done simply with the if statement:
if some_option then
    my_table = { ... }

    function foo()
        ...
    end
else
    ...
end

Some argue that this will still generate byte code, wasting CPU time and memory. Since conversion to byte code can always be done offline, the issue of CPU time can be easily resolved. Regarding memory, byte code size is often insignificant compared to dynamic memory usage. Nonetheless, a solution for avoiding unecessary byte code is to use the C preprocessor:

#if SOME_OPTION
    my_table = { ... }

    function foo()
        ...
    end
#else
    ...
#endif

For example, using gcc, the code above can be run like this:

gcc -E -P -DSOME_OPTION -x c test.lua | lua

Why doesn't the __gc and __len metamethods work on tables?

Note: Lua 5.2 and beyond do support __gc and __len. The below answer is for prior versions.

Userdata objects frequently require some explicit destructor to run when the object is about to be deleted, and Lua provides the __gc metamethod for that purpose. However, this is not allowed on tables for efficiency.

Normally, there is no need to set a destructor on a table, since the table will be deleted automatically, and any references the table contains will then be garbage collected normally. A possible workaround is to create a userdata; make the table the userdata's environment table, and place a reference to the userdata in the table. (Make sure that this is the only reference to the userdata.) When the table becomes collectable, the userdata's __gc metamethod will be run; Lua will not actually destroy the table before that happens because the table is referenced by the userdata.

__len on tables is scheduled to be supported in 5.2. See LuaFiveTwo.

Why does Lua lack the += operator, etc.?

One of Lua's design goals is simplicity. Most languages are large, meaning that they have many sophisticated features built-in. Examples are C, C++, Python, Lisp, ML. A very few languages are small. Examples are Forth and Lua. Lua aims to provide a small range of atomic features which are truly essential, and from which many other sophisticated features can be constructed if desired. Examples of sophisticated features which can be added to Lua from within the language include modules, object orientation, and now exceptions and threads which can be implemented via coroutines in Lua 5. The absent += operator is one more example.

I thought the reason was more practical. Many argue for adding these operators because of the efficiency gains they enable. But in Lua things would get confusing because of the extension system. It's in the lua-l archives somewhere... --JohnBelmonte

I think it's more basic than that - you must draw a line in the sand for the amount of operators a small language should have. You allow +=, then people ask why not *= and -= etc etc. Before you know it, you have added many operators which simply makes it bigger. Small and simple is Lua's tenet.

If you really want to, see CustomOperators.

Why won't this Lua code off the internet execute? (Converting to Lua 5)

From Lua 4.x to Lua 5.0, most library functions were moved into tables -- for instance, read() and write() now must be accessed from a global table, for instance, as io.read() or io.write(). Other functions, such as readfrom(), no longer exist. (io.popen() can be used if supported by your platform.)

There were also a variety of syntactical changes; the %upvalue syntax no longer exists, since Lua has true lexical scoping since version 5.0; % is now the remainder operator.

The use of the special arg variable for vararg functions is deprecated, and will be removed from a future version. Vararg functions should be rewritten to use the new ... pseudo-value, but a short-term workaround is to start the function with:

function va(x, ...)
  local arg = { n=select('#', ...), ... }
  -- rest of function
end

Since Lua 5.1, the abbreviated for k, v in tab syntax no longer works; it should be replaced by for k, v in pairs(tab).

Any code which used tagmethods will have to be rewritten to use metamethods instead.

In case of desperation, old versions of Lua continue to be available in source form from the Lua webpages.

Related - LuaFiveFeatures, MigratingToFiveOne.

What does "[C]:" refer to in error messages?

It means the error occurred inside a C/C++ function.

How can I avoid reloading Lua files from harddisk?

When a file is read, the whole content is compiled into a normal Lua function. Since Lua functions can be stored in any normal variable, you can avoid reloading files by keeping the compiled function somewhere. As an example:

foo = assert(loadfile("foo.lua")) -- if there is an compilation error, the script will raise an error here
for i=1,100 do 
  foo() -- call the script file's function 100 time - the file is not loaded from HD!
end

Lua API Programming

How can I compile C programs that use Lua?

If you use gcc as a compiler, execute the following command:

gcc -llua program.c -o outputfile

You may also need to link against some more libraries. Add the following paramaters to the above command if necessary.

-lm #link against the math library

-ldl #link against the dl library

Lua isn't working with my C++ program! Why am I getting compiler and linker errors?

Lua indeed works with C++. You need to extern "C" the Lua header files since they are ANSI C headers. See the next FAQ and BuildingLua. For a more sophisticated solutions, see "Code wrappers" on LuaAddons.

I'm getting segfaults when I run my Lua script. Why doesn't Lua catch the errors?

Lua does not verify that API calls have correct arguments. You have probably corrupted the stack, referenced an invalid stack index, or pushed too many things on the stack (see luaL_checkstack()). Enable api checking while you are debugging. For Lua 5.1, compile with -DLUA_USE_APICHECK; see this message for Lua 5.0 instructions: [4]

I get mysterious crashes or malloc errors in the middle of ltable.c

Most likely, you have created an executable with two copies of liblua. This typically happens when you statically link liblua into a dynamically loadable extension module.

As of Lua 5.0, this configuration is not supported; you may only have one instance of liblua in a given execution image.

My application used to work, but I updated it to Lua 5.1 and it now crashes during initialization (OR: Why do I get a "no calling environment" error?)

The state initialization procedure changed between Lua 5.0 and Lua 5.1. It is now necessary to lua_call the various luaopen_* functions. Previously, these were simply called with a normal C call, but doing so now will cause a crash (or the above mentioned error) during the initialization of the io library.

The easiest way to initialize a lua_State is to use luaL_openlibs() which is defined in the file linit.c, or to copy the code from that file, modifying the list of libraries to initialize according to your needs.

Why isn't there an extern "C" block, required for C++, in the API header?

Lua is implemented in ANSI C. No special treatment is given for the import of its interface into other languages, including C++. To use the Lua header in C++, wrap it externally:
extern "C" {
    #include "lua.h"
}

Another reason is that Lua is also correct C++ code. You can compile Lua with a C++ compiler without any changes. If it had the extern "C" declaration, Lua would generate a C interface even when compiled as a C++ library. See BuildingLua.

I heard Lua is implemented using a VM (like Java). Is it documented? Can I write VM instructions directly?

Yes, Lua is implemented using a Virtual Machine. Lua translates Lua code into blocks of VM instructions and then executes the VM instructions.

The VM format is not publicly documented and is likely to change at the whim of the Lua developers. It isn't really recommended to try and write VM instructions directly.

I have a sneaking suspicion that someone (not a Lua developer) on the list wrote a document describing the VM instructions.

If you're interested in this kind of thing, you can use luac -l (luac is provided in the standard distribution) to see the VM instructions that Lua compiles a source into. It's also not too hard to poke about in the sources to Lua to see what is going on (see lvm.c in the standard distribution).

What to do when a _CrtIsValidHeapPointer assertion failure happens?

When doing Lua embedding, sometimes if you didn't clean the stack correctly, it might cause a _CrtIsValidHeapPointer assertion failure.

As the comment of the function _CrtIsValidHeapPointer says: "verify pointer is not only a valid pointer but also that it is from the 'local' heap. Pointers from another copy of the C runtime (even in the same process) will be caught."

Let's check the details of the 'invalid pointer'. When lua_open() return a lua_State* L, it's with a stack of default size 45. If you make some fault not clear the return values of function, that garbage will finally pile up on the stack and crash the stack memory block. When a new op needs to increase the stack size, a realloc will happen, and the CRT will find that the old pointer is invalid and this will lead a _CrtIsValidHeapPointer failure.

To fix, just carefully check your code (using lua_gettop(L) to check the stack size) and clean the unused slot on the stack.

For the 'non local heap' one, please check and make sure Lua lib doesn't have a separate copy of CRT.

More details can be found here:http://www.blogcn.com/User4/al_lea/blog/39582295.html

Why does luaopen_io need to be lua_called? (OR: Why does my library-created file segfault on :close() but work otherwise?)

The POSIX.1 standard specifies that one must use pclose instead of fclose to close a FILE* created with popen. The IO library uses function environments to specify on a per-file basis which close function is to be used. luaopen_io sets its own function environment so that the iolib functions that don't specify otherwise implicitly use fclose.

If you were to call luaopen_io directly instead of with lua_call, it would set the calling C function's function environment. (Worse, if you're calling it from the "outside", there will not even be a calling C function, and bad stuff will happen.) Using lua_call saves that from happening.

Also, if you're writing a Lua library and you want to return an iolib file handle, it's not as easy as it could be. On top of getting and using the metatable for "FILE*", you have to specify a __close in the function environment of your userdata (or the function creating it).

For example:

  /* when registering the C function that returns a file handle */
  lua_pushcfunction(L, mycfunction);
  lua_newtable(L);
  lua_pushcfunction(L, myclose);
  lua_setfield(L, -2, "__close");
  lua_setfenv(L, -2);

  /* when creating the actual filehandle */
  FILE** p = (FILE**)lua_newuserdata(L, sizeof(FILE*));
  luaL_getmetatable(L, "FILE*");
  lua_setmetatable(L, -2);
  *p = myfile;

How can I traverse a table in C?

Use lua_next[5]. If the table is an array, you can instead call lua_gettable[6] or lua_rawgeti[7] in a loop that exits when nil is found or lua_objlen[8] is reached. In other cases, its more convenient to call a Lua function that iterates over the table (see TableSerialization).

What makes Lua any more embeddable than other languages?

The main problem with embedding third-party code is that the host software (or the programmers) must sometimes adapt to fit around it. Lua adopts a number of strategies to prevent responsibilities from leaking between the embedded interpreter and the host program. If you have had previous experience with embedded interpreters, you might be inclined to ask some of the following questions.

Wouldn't an embedded unit limit my choice of platforms and compilers?

The core source code of some projects relies heavily on OS-specific system calls. This situation is likely to occur when the software is developed primarily for a popular platform and then other platforms are supported via independent porting projects. Each porting project can follow its own agenda without worrying about the others. Conditional compilation (#ifdef, etc) is often used to provide separate code sequences for each supported platform.

This approach seems reasonable but the code may vary in quality among the platforms and the less popular ports may only appear months after each official release. If such code is embedded then the host program will only be able to run on the platforms supported by the embedded unit. If the host is to have identical features across all target platforms, then it may be necessary to delay development until all the ports are in alignment or else to use a less recent version of the unit.

Furthermore, some C source code uses non-standard features of a particular compiler. This is another common symptom of independent porting projects - each project can simply require developers to use the most popular compiler for their target platform. If an embedded unit depends on special features of compiler X then the host might also need to be compiled with compiler X. If, at this point, the host is already relying on different non-standard features of compiler Y then either the unit or the host might require heavy modification.

Lua avoids all these problems by sticking to the common subset of ANSI C and C++ in its source. This gives the interpreter the best possible chance of working with whatever compiler is already being used for the host. Additionally, Lua uses no OS-specific routines and the exact same code base builds correctly on all known platforms.

If I embed the Lua source, won't it clash with my coding habits?

Some organisations operate code quality policies that require programmers to eliminate all compiler warnings as they go along. Under these conditions, an embedded unit can be a major problem if its code generates warnings. At best, it might be necessary to check the list of warnings during every compilation to ensure none of them originated from the host program. At worst, it might be necessary to modify all offending code in the unit. A modified unit is, of course, no longer consistent with the standard distribution and so the same modifications will likely have to be repeated each time a new version of the unit is released. (An open source project might allow the modifications to be commited back to the main codebase, but there is no guarantee that other developers will maintain the same level of discipline in the future.)

Lua is designed with this issue in mind. During testing, the source is compiled with the maximum level of warnings on a number of compilers. Any resulting warnings are eliminated before the code is released.

Will the API force me to use the interpreter's complex structures to exchange data?

Internally, an embeddable unit of code may use complex and esoteric data structures, often for perfectly valid reasons. However, if the unit's API also relies on these structures then the embedder may be forced to spend time learning the unit's way of doing things. This so-called "impedance mismatch" is particularly likely when embedding a scripting language. Some interpreters require their initial state (global variables, etc) to be set up by the host using the interpreter's data structures. Also, it will usually be necessary for the host and the interpreter to exchange data values from time to time. Ideally, the host shouldn't be forced to use the interpreter's structures for its own data or else to perform troublesome conversions each time data is exchanged.

Lua has a simple API where the initial state is created without using any of the interpreter's internal structures. Furthermore, data is exchanged with the host via a simple stack which receives and produces values in their natural C datatype.

The flipside of this issue is that the interpreter could use simple, well-behaved types in its API, but then require the host to reduce its own esoteric data to these types for purposes of exchange. This also forces the host to use conversion routines or to represent its own data in simple, unstructured types throughout. Lua's answer is to allow so-called userdata types. These are blocks of memory that Lua does not "understand" directly but which it can manipulate via callbacks to the host. Thus the standard Lua operations can be made to work directly on the host's data as if it were native to the interpreter.

Could Lua's memory management clash with the host's requirements?

Lua uses its own automatic memory management which operates in a memory space of a fixed size determined by the host program. This means that no system calls will be needed to allocate memory during script execution. An interpreter can therefore be used in situations where such calls are unsafe.

However, automatic memory management can create problems in itself. Some garbage collection systems suffer from "pregnant pauses" where the main program freezes during collection cycles. Lua's incremental collection has the same time overheads as other techniques, but it spreads them evenly in small steps over the program's execution. Latency in such a system is very consistent, possibly even more so than in systems that use manual memory management. Furthermore, the time between collection steps and the time spent on each step can be controlled by the host on the fly. An embedded Lua can therefore be configured and tested for a specific latency requirement quite easily and should pass or fail tests cleanly during development rather than creating surprises after deployment.

For maximum flexibility, Lua can optionally store the host's userdata objects in its own memory space or let the host manage their memory explicitly. The host need not be wary of garbage collection for data it shares with the interpreter.

Wouldn't an interpreter be too resource-hungry to embed in a limited system?

Lua code can be stored and loaded in a pre-compiled binary form which can be generated by its standard compiler tool, luac. The binary form is more memory-efficient than source text, but also allows another possibility for the interpreter: the parsing/compiling code can be removed altogether. This reduces the size of the already small Lua core to about 40K. Lua programs in binary form can also be encoded as C strings and easily stored in the host's source code. It is therefore convenient to use Lua in devices that lack a filesystem.


NOTES


RecentChanges · preferences
edit · history
Last edited May 15, 2020 7:38 pm GMT (diff)