奇怪的结果从堆栈读取索引0

Weird results reading index 0 from the stack

本文关键字:读取 索引 堆栈 结果      更新时间:2023-10-16

通常Lua堆栈从索引1开始。但是,在读取调用cfunction提供的堆栈地址0时,我注意到一个奇怪的现象。

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

上面看到的所有表(h, u和嵌套的s)都有一个指向相同c函数的__call元方法。从那个cfunction中,我读取/转储了传递的堆栈:

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

start_index从1开始时,输出如预期:LUA_TABLE LUA_TNUMBER:3;它包含包含元方法(至少我认为是这样)和参数3的表。


然而,当start_index从0开始时,我认为结果不是有效的Lua类型,但它是。结果是不一致的:当从Lua调用时,索引0始终是值为5LUA_TNUMBER

然而,当在c++中调用pcall (lua_getfield, lua_pushnumber, lua_pcall)时,索引0对于调用f.u.s产生相同的LUA_TNUMBER(5),但是对于hu产生相同的LUA_TABLE

在索引0处是什么,为什么它是一个有效的Lua类型,为什么它的值如此奇怪地不一致?

0不是一个有效的堆栈索引,所以您不能指望在那里找到任何东西。这有点像拿你的lua_State指针和解引用(lua_State - 1),并询问有什么值。这是垃圾。

来自Lua手册:

API中任何接收堆栈索引的函数只能使用有效索引可接受索引

有效索引是指向堆栈内实际位置的索引,即它的位置介于1和堆栈顶部(1 = abs(index) = top)之间。

可接受的索引可以是任何有效索引,包括伪索引,但它也可以是堆栈顶部之后为堆栈分配的空间内的任何正索引,即到堆栈大小的索引。

(注意0绝不是可接受的索引)

查看源代码(参见index2addr),看起来如果Lua是用LUA_USE_APICHECK构建的,那么您的调用将抛出一个错误。