cffi-lua icon indicating copy to clipboard operation
cffi-lua copied to clipboard

Boxed integers cannot be compared to numbers

Open rweichler opened this issue 7 months ago • 2 comments

Repro code:

print(ffi.new('uintptr_t', 20) == 20)

It will print true with LuaJIT's ffi, and print false with this ffi.

rweichler avatar Jun 02 '25 17:06 rweichler

Actually I'm not entirely sure if LuaJIT's behavior is strictly better since this returns true in LuaJIT:

print(0xfffffffffffffffffffffffffffffffffffffffff == 0xffffffffffffffffULL)

rweichler avatar Jun 02 '25 17:06 rweichler

Checked the docs and yea there's a discrepancy here:

https://github.com/q66/cffi-lua/blob/master/docs/semantics.md?plain=1#L396-L398

  • 64-bit integer comparison: two cdata number or a cdata number and a Lua number can be compared. The same conversions as in arithmetic are performed first, same with enums.

So unless I am horribly mistaken, either the docs need to be changed or the behavior needs to be changed

rweichler avatar Jun 02 '25 19:06 rweichler

Checked the docs and yea there's a discrepancy here:

https://github.com/q66/cffi-lua/blob/master/docs/semantics.md?plain=1#L396-L398

  • 64-bit integer comparison: two cdata number or a cdata number and a Lua number can be compared. The same conversions as in arithmetic are performed first, same with enums.

So unless I am horribly mistaken, either the docs need to be changed or the behavior needs to be changed

readme.md

Equality comparisons between cdata and Lua values are always false

ChrisCatCP avatar Jun 14 '25 03:06 ChrisCatCP

the lua metamethod semantics don't allow this to work, quoting reference manual:

"eq": the == operation. The function getcomphandler defines how Lua chooses a metamethod for comparison operators. A metamethod only is selected when both objects being compared have the same type and the same metamethod for the selected operation.

the cffi doc states that immediately after:

  • Equality comparisons never raise an error, but a notable difference from LuaJIT is that metamethods are only ever triggered on compatible Lua types, which means comparisons of cdata and nil (or other Lua values) will always be false no matter what. Incompatible cdata pointers can always be tested for address equality.

"comparison" in the above doc refers to operators like </>, which do work

q66 avatar Jun 14 '25 04:06 q66

Thanks. That is unfortunate. I guess in order to get boxedInt == luaNumber to behave like one would expect, you would have to do something like boxedInt >= luaNumber and boxedInt <= luaNumber. Very strange.

Edit: Maybe change the docs to say something like "64-bit integer >, >=, <, <= comparisons" instead of "64-bit integer comparison"?

rweichler avatar Jul 15 '25 17:07 rweichler

you can convert the lua number to a boxed number and then do equality comparison

q66 avatar Jul 15 '25 18:07 q66

I suppose that works too. I forgot why I didn't go with that approach.... it's been a while.

rweichler avatar Jul 15 '25 20:07 rweichler