lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]

Thanks, I can see that since lua_touserdata returns NULL, the type error is signalled. What I'm really asking is if lua_touserdata works if the stack index is not present. (The docs say it requires an "acceptable" index.)

LUA_API void *lua_touserdata (lua_State *L, int idx) {
  StkId o = index2adr(L, idx);
  switch (ttype(o)) {
    case LUA_TUSERDATA: return (rawuvalue(o) + 1);
    case LUA_TLIGHTUSERDATA: return pvalue(o);
    default: return NULL;

I think this boils down to a question of what index2adr does if the index is not valid. It looks to me like it returns a "nil object" which presumably ttype is OK with:

static TValue *index2adr (lua_State *L, int idx) {
  if (idx > 0) {
    TValue *o = L->base + (idx - 1);
    api_check(L, idx <= L->ci->top - L->base);
    if (o >= L->top) return cast(TValue *, luaO_nilobject);
    else return o;

Is the api_check always present, or is it more like an assert?

I think I should spend more time reading the Lua source. :-)

On Thu, Feb 21, 2013 at 4:42 PM, Sean Conner <> wrote:
It was thus said that the Great Marc Lepage once stated:
> Apologies for another silly little question.
> In C code, for 5.1, if I call luaL_checkudata but the index doesn't exist
> (say I was expecting an arg but none was provided), is that OK (and I get
> expected failure) or is that somehow bad or undefined?

  luaL_checkudata() will raise an error if the item at the given stack index
does not exist, or isn't a userdata.  This error can be caught by pcall()
(in Lua) or lua_pcall() (in C) but I rarely do that in my code.

> In the implementation, I can see it calls:
> lua_touserdata: If the value at the given acceptable index is a full
> userdata, returns its block address. If the value is a light userdata,
> returns its pointer. Otherwise, returns NULL.

  But it calls luaL_typerror() when lua_touserdata() returns NULL, and it's
luaL_typerror() that causes the error to be raised (even though
luaL_checkudata() looks as if it returns NULL, that statement is never
reached and exists, as the comments there says, to keep compilers from

> So I guess my question is whether, if I was expecting an arg and it wasn't
> provided, is that an "acceptable index?" (Or, if it's not acceptable,
> that's the "otherwise" clause?)

  I wouldn't worry about it.  Here's some C code [1]:

static int tcclua_define(lua_State *const L)
          *(TCCState **)luaL_checkudata(L,1,TCC_TYPE),
  return 0;

And if that function is called with no parameters:

Lua 5.1.5  Copyright (C) 1994-2012, PUC-Rio
> tcc = require "org.conman.tcc"
> cc  =
> cc.define()
stdin:1: bad argument #3 to 'define' (string expected, got no value)
stack traceback:
        [C]: in function 'define'
        stdin:1: in main chunk
        [C]: ?

Call it correctly though:

> cc:define("FOO","bar")

And everything is fine.

  -spc (So, why does it trigger on parameter 3 first?  Because of the rules
        of C when evaluating parameters of a function---they're evaluated
        from right to left.  Why that way?  I'll leave that as an exercise
        for the reader ... )

[1]     Part of a Lua interface to TCC [2][3].  Code can be views here


[3]     I based the code on the following TCC codebase: