[Haskell-cafe] Nice addition to Foreign: castAny
John Meacham
john at repetae.net
Tue Nov 3 23:34:39 EST 2009
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/
More information about the Haskell-Cafe
mailing list