سؤال

Normally the Lua stack begins at index 1. However, I noticed a strange phenomenon when reading the stack address 0 provided by calling a cfunction.

--lua tables defined via Lua C API
h{ }
u{ }
f{ u{ s{} } }
--table calls
h(2)
u(3)
f.u.s(4)

All the above seen tables (h, u, and the nested s) have a __call metamethod pointing to the same cfunction. From that cfunction I'm reading/dumping the passed stack:

while(start_index <= lua_gettop(state)) {
    switch(lua_type(state, start_index)) {
        case LUA_TNUMBER:
            std::cout << "LUA_TNUMBER:"<<lua_tonumber(state, start_index);
            break;
        //... dump for all the other types

When start_index starts at 1, the output is as expected: LUA_TABLE LUA_TNUMBER:3; It contains the table that contains the metamethod (or so I think) and the argument, 3.


However when start_index starts at 0, I'd imagine the result is not a valid Lua type, but it is. The results are inconsistent: When calling from Lua, index 0 is always a LUA_TNUMBER with the value 5.

When however calling from C++ with pcall (lua_getfield, lua_pushnumber, lua_pcall), index 0 yields the same LUA_TNUMBER(5) for calling f.u.s, but LUA_TABLE for h and u.

What is at index 0, why is it a valid Lua type, and why is its value so weirdly inconsistent?

هل كانت مفيدة؟

المحلول

0 is not a valid stack index, so you can't rely on finding anything there. It's kinda like taking your lua_State pointer and dereferencing (lua_State - 1) and asking what the value there is. It's garbage.

From the Lua manual:

Any function in the API that receives stack indices works only with valid indices or acceptable indices.

A valid index is an index that refers to a real position within the stack, that is, its position lies between 1 and the stack top (1 = abs(index) = top).

An acceptable index can be any valid index, including the pseudo-indices, but it also can be any positive index after the stack top within the space allocated for the stack, that is, indices up to the stack size.

(Note that 0 is never an acceptable index)

Looking at the source (see index2addr), it looks like if Lua is built with LUA_USE_APICHECK, your call would thrown an error.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top