2
votes

I am using the Lua API for C/C++ to create functions in C/C++ and then register them for use in Lua scripts. Obviously these functions expect a certain number of arguments with specific types, which is no problem in C/C++ because of static typing. However, given that Lua is dynamic, I need to manually check the number of arguments passed and their types when I call this C-function from Lua. These arguments are pushed onto the Lua stack, so I can check the number of arguments with lua_gettop and then check their individual types with lua_type.

My question, though, is can I guarantee the number of elements on the stack, that is, the number of arguments passed to my function? That way, I could check this at the beginning of my C-function with an assertion: assert(lua_gettop(L) == x), with x just being a placeholder for the desired number of arguments and L being a lua_State*. This extends a little deeper, as I wonder if other functions that interact with the Lua stack clean up so that the stack is empty when I call this function; otherwise, if some things were left sitting on the stack from a previous function call, the assertion would fail. Below is a simple example.

C/C++ code:

int foo(lua_State* L) {
    assert(lua_gettop(L) == 2);

    // do stuff

    return 1;
}

Calling the function in Lua. Assume that the function expects two strings as arguments; thus, the first call would succeed and the second would fail.

foo("hello", "world")
foo("hello", "world", 1)
1

1 Answers

3
votes

If you have directly registered a function to Lua, and a Lua script calls that function with N arguments, then that function will have N values on the stack when it gets called. That's how it works, and no process can interfere with this (well, you could manually call that function from C with an improper lua_State, but that's your fault).

So long as you don't do any stack manipulation between the start of that function and whatever you use to check the current stack size, then your test will be accurate.

Every Lua function is well-documented in how (or if) it manipulates the stack. Whether it inserts values to the stack, removes them from the stack, and so forth.

That being said, assert is probably the wrong tool. If the user provides the wrong number of parameters, and you consider that erroneous behavior, you should invoke lua_error. And not just on debug builds.