I've recently been looking around at various Haskell quirks, like unboxed types and whatnot, when I discovered the Addr#
type.
The GHC.Prim
package describes it as so:
An arbitrary machine address assumed to point outside the garbage-collected heap.
And that means not much to me.
Furthermore, I keep finding functions like this that use the type:
readIntOffAddr# :: Addr# -> Int# -> State# s -> (#State# s, Int##)
What is this type? What can I do with it? Why is it necessary?
The equivalent* C code would be:
long readIntOffAddr(long *ptr, long offset) {
return ptr[offset];
}
Addr#
is just like void *
. The function has an IO
-like signature because it is not "pure". Multiple calls to the function may return different values (obviously).
* Update (2018): I just learned that equating C's int
type with Haskells Int#
type is wrong. So I changed int
to long
in the above code snippet. This is also (maybe) not 100% correct, but at least it is true for all GHC implementations that I have seen. In GHC versions 6-8 (haven't checked others), Int#
is 32 bit wide on 32-bit platforms and 64 bit wide on 64-bit platforms. This matches the behaviour of GCC for long
for all C/C++ implementations on 32-bit and 64-bit platforms that I am aware of, so I think equating Int#
with long
is a good first approximation. No one noticed this minor inaccuracy in the last 3 years (or cared enough to edit/comment). I doubt that there is any Haskell/Platform/C combination where HsInt
!= long
where the Haskell implementation has a readIntOffAddr#
function.. please prove me wrong.