lua-users home
lua-l archive

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


On 16 November 2014 22:43, Eric Wing <ewmailing@gmail.com> wrote:
> On 11/16/14, Luiz Henrique de Figueiredo <lhf@tecgraf.puc-rio.br> wrote:
> My biggest stumbling block with the float-integer conversion in my
> project was that I have 2 separate C libraries I'm binding to. One
> library is a physics library (Chipmunk) which uses floating point. The
> other is a graphics library (SDL) which uses integer. The physics is
> the "model" of the object and drives the "view". So the natural
> inclination is just to hand off the physics results to the graphics,
> but for non-intergral values, all my values turned to 0.
>
> (I should note that I don't remember lua_tointeger dropping
> non-integral numbers to 0 in Lua 5.1. Assuming this is a change, I do
> consider this surprising and might cause other legacy bindings
> problems like mine.)

Ouch.

Just checked the manuals.

----------------------------------------
Lua 5.2:
http://www.lua.org/manual/5.2/manual.html#lua_tointeger

lua_tointeger:
   lua_Integer lua_tointeger (lua_State *L, int index);
   Equivalent to lua_tointegerx with isnum equal to NULL.

lua_tointegerx:
   lua_Integer lua_tointegerx (lua_State *L, int index, int *isnum);
   Converts the Lua value at the given index to the signed integral
   type lua_Integer. The Lua value must be a number or a string
   convertible to a number (see §3.4.2);
   otherwise, lua_tointegerx returns 0.

   If the number is not an integer, it is truncated in some
   non-specified way.

   If isnum is not NULL, its referent is assigned a boolean value that
   indicates whether the operation succeeded.
----------------------------------------
Lua 5.3:
http://www.lua.org/work/doc/manual.html#lua_tointeger

lua_tointeger:
   lua_Integer lua_tointeger (lua_State *L, int index);
   Equivalent to lua_tointegerx with isnum equal to NULL.

lua_tointegerx:
   lua_Integer lua_tointegerx (lua_State *L, int index, int *isnum);
   Converts the Lua value at the given index to the signed integral
   type lua_Integer. The Lua value must be an integer, or a number
   or string convertible to an integer (see §3.4.3);
   otherwise, lua_tointegerx returns 0.

   If isnum is not NULL, its referent is assigned a boolean value
   that indicates whether the operation succeeded.
----------------------------------------

Borrowing Tim's crystal ball, I foresee that this indirect change in
the behavior of lua_tointeger (caused by the change in lua_tointegerx)
will take lots of people by surprise and silently break code out
there. The Lua authors will be rightfully justified in blaming the
module authors for relying on explicitly non-specified conversions,
but since the conversions are more strict now in the Lua side too
(generating obvious errors as pointed by Liam's original email), then
perhaps the definition of lua_integer could be updated into something
like the (untested) code below?

lua_Integer lua_tointeger (lua_State *L, int index) {
  int isnum;
  lua_Integer num = lua_tointegerx(L, index, &isnum);
  if (!isnum) {
    lua_pushliteral(L, "number has no integer representation");
    lua_error(L);
  }
  return num;
}

This would probably save a lot of headache, and people who know what
they're doing and care for the last drop of performance in the Lua/C
API can always use lua_tointegerx(L, index, NULL) explicitly.

-- Hisham