[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: `string.unpack` 's bug in option `z`
- From: Sean Conner <sean@...>
- Date: Mon, 3 Sep 2018 16:54:12 -0400
It was thus said that the Great Daurnimator once stated:
> On 3 September 2018 at 02:51, Dirk Laurie <dirk.laurie@gmail.com> wrote:
> > BTW that library is a beautiful example of how to write C API code
> > that compiles on all Lua versions from 5.0 to 5.4 with only this
> > version-dependent test:
> >
> > #if (LUA_VERSION_NUM >= 502)
> > #define luaL_register(L,n,f) luaL_newlib(L,f)
> > #endif
>
>
> I object: people should be writing against the newest lua version
> available at the time, and using the preprocessor to gain *backwards*
> compatibility.
> Defining *older* functions in terms of new ones (forwards
> compatibility) is in my opinion, an antipattern used for quicker
> porting.
But there's still an issue. Take the following hypthetical Lua 5.1 code:
static luaL_Reg const m_foo_reg[] = { /* ... */ };
int luaopen_foo(lua_State *L)
{
luaL_register(L,"foo",m_foo_reg);
return 1;
}
The semantics of Lua 5.1 include the creation of the global "foo". If I go
ahead and do this:
#if LUA_VERSION_NUM == 501
# define luaL_newlib(state,reg) luaL_register((state),NULL,(reg))
#endif
static luaL_Reg const m_foo_reg[] = { /* ... */ };
int luaopen_foo(lua_State *L)
{
luaL_newlib(L,m_foo_reg);
return 1;
}
This can *break* code on Lua 5.1---the global "foo" is not created. Yes, I
could get around this [1]:
#if (LUA_VERSION_NUM == 501)
# define luaL_newlib(state,reg) luaL_register((state),"foo",(reg))
#endif
but I'm not happy with that solution for this particular case. What I
normally do is:
static luaL_Reg const m_foo_reg[] = { /* ... */ };
int luaopen_foo(lua_State *L)
{
# if LUA_VERSION_NUM == 501
luaL_register(L,"foo",m_foo_reg);
#else
luaL_newlib(L,m_foo_reg);
#endif
return 1;
}
which I'm not happy with either, but I think is "better" in that the name of
the module is closer to it's use than buried in a #define elsewhere. Yes, I
could do the #define closer to this point, but that breaks my own coding
style.
Another problematic pair of functions is lua_objlen() (Lua 5.1) and
luaL_len() (Lua 5.2+). luaL_len() is *not* a direct replacement for
lua_objlen(), because one raises an error and one doesn't.
-spc
[1] As I did here:
https://github.com/spc476/lua-conmanorg/blob/380c78b15d0211f794be5ff94daefc0fed30e333/src/tls.c#L48