James Bielman wrote:
By the way, I was looking into writing a regression test for this and had problems since we also use FOREIGN-ADDRESS-UNSIGNED to implement POINTER-EQ. Could we be using EQUALP instead for comparing pointers (or is the fact that seems to work just a coincidence?)
I was considering adding pointer-eq to the FFI, since even with 32bit, the current cffi:pointer-eq implementation is likely to cons bignums. So far, every null-pointer test conses a bignum, just to test against 0.
The irony of history is that, the FFI once had FFI:NULL-POINTER-P (sp?). It was deprecated when the FFI was reviewed to consistently return NIL for NULL.
Later, I added unsigned-foreign-address. After some thought, I decided I'd let it create a #<pointer> object from 0, instead of returning NIL. I thought, "if people really want to obtain a pointer with address 0 using this low-level function, let them do it".
Nowadays, CFFI uses these presumably low-level primitives a lot. I.e. the useage pattern differs between programs using FFI and CFFI. The fact that there's an exception to the NIL<->NULL rule means that robust code implementing cffi:NULL-POINTER-P must test both cases, causing duplication of work (and so far, consing).
Solutions: A Reintroduce ffi:null-pointer-p, not consing.
B Change unsigned-foreign-address to return NIL instead of #<foreign-address #x0000000>. There would be (almost?) no more exception, and null-pointer-p would become equivalent to cl:NULL.
C Implement cffi:null-pointer-p via cl:NULL and don't worry about somebody asking for (unsigned-foreign-address 0) returning something else. It might work in practice. There's just the one CFFI testcase (null-pointer-p (make-pointer 0)) (oh, it's been removed).
Comments?
I'm considering A+B, together with pointer-eq. Jorg Hohle.