This first edition was written for Lua 5.0. While still largely relevant for later versions, there are some differences.
The fourth edition targets Lua 5.3 and is available at Amazon and other bookstores.
By buying the book, you also help to support the Lua project.

24.2.2 – Querying Elements

To refer to elements in the stack, the API uses indices. The first element in the stack (that is, the element that was pushed first) has index 1, the next one has index 2, and so on. We can also access elements using the top of the stack as our reference, using negative indices. In that case, -1 refers to the element at the top (that is, the last element pushed), -2 to the previous element, and so on. For instance, the call lua_tostring(L, -1) returns the value at the top of the stack as a string. As we will see, there are several occasions when it is natural to index the stack from the bottom (that is, with positive indices) and several other occasions when the natural way is to use negative indices.

To check whether an element has a specific type, the API offers a family of functions lua_is*, where the * can be any Lua type. So, there are lua_isnumber, lua_isstring, lua_istable, and the like. All these functions have the same prototype:

    int lua_is... (lua_State *L, int index);
The lua_isnumber and lua_isstring functions do not check whether the value has that specific type, but whether the value can be converted to that type. For instance, any number satisfies lua_isstring.

There is also a function lua_type, which returns the type of an element in the stack. (Some of the lua_is* functions are actually macros that use this function.) Each type is represented by a constant defined in the header file lua.h: LUA_TNIL, LUA_TBOOLEAN, LUA_TNUMBER, LUA_TSTRING, LUA_TTABLE, LUA_TFUNCTION, LUA_TUSERDATA, and LUA_TTHREAD. This function is mainly used in conjunction with a switch statement. It is also useful when we need to check for strings and numbers without coercions.

To get a value from the stack, there are the lua_to* functions:

    int            lua_toboolean (lua_State *L, int index);
    double         lua_tonumber (lua_State *L, int index);
    const char    *lua_tostring (lua_State *L, int index);
    size_t         lua_strlen (lua_State *L, int index);
It is OK to call them even when the given element does not have the correct type. In this case, lua_toboolean, lua_tonumber and lua_strlen return zero and the others return NULL. The zero is not useful, but ANSI C provides us with no invalid numeric value that we could use to signal errors. For the other functions, however, we frequently do not need to use the corresponding lua_is* function: We just call lua_to* and then test whether the result is not NULL.

The lua_tostring function returns a pointer to an internal copy of the string. You cannot change it (there is a const there to remind you). Lua ensures that this pointer is valid as long as the corresponding value is in the stack. When a C function returns, Lua clears its stack; therefore, as a rule, you should never store pointers to Lua strings outside the function that got them.

Any string that lua_tostring returns always has a zero at its end, but it can have other zeros inside it. The lua_strlen function returns the correct length of the string. In particular, assuming that the value at the top of the stack is a string, the following assertions are always valid:

    const char *s = lua_tostring(L, -1);   /* any Lua string */
    size_t l = lua_strlen(L, -1);          /* its length */
    assert(s[l] == '\0');
    assert(strlen(s) <= l);