
On Tue, Oct 27, 2009 at 12:48:32AM -0200, Maurício CA wrote:
This could be beside castPtr, castCharToCChar etc.
----
castAny :: (Storable a, Storable b) => a -> b castAny = unsafePerformIO . genericCast where genericCast :: (Storable a, Storable b) => a -> IO b genericCast v = return undefined >>= \r -> allocaBytes (max (sizeOf v) (sizeOf r)) $ \p -> poke p v >> if False then return r else peek (castPtr p)
----
GHCi:
let a = -1000 :: Int16 castAny a :: Word16 --> 64536 castAny a :: Ptr () 0xb4c2fc18 castAny (castAny a :: Ptr ()) :: Int16 -1000
let b = pi :: CLDouble b 3.141592653589793 castAny b :: CInt 1413754136 castAny b :: Ptr () 0x54442d18 castAny b :: CFloat 3.3702806e12 castAny b :: Int8 24
At minimum, this is safer than 'unsafeCoerce'. What do you think?
Try it on a big endian architecture, or one that has alignment restrictions, or a different size for HsChar or so forth. Casting by 'punning' (as the C folks like to call it) does have uses, but they are generally hardware dependent and useful only in certain rare circumstances that a generic cast probably isn't likely to fill. John -- John Meacham - ⑆repetae.net⑆john⑈ - http://notanumber.net/