Unsafe aspects of ByteString

Donald Bruce Stewart dons at cse.unsw.edu.au
Sun Jan 28 19:53:48 EST 2007


iavor.diatchki:
> Hello,
> 
> On 1/28/07, Duncan Coutts <duncan.coutts at worc.ox.ac.uk> wrote:
> >We can put them in the IO monad. The same applies to packCStringLen and
> >packMallocCString.
> 
> Adding packCString (and friends) to the IO monad does not make them
> any safer (the IO monad hides some sins but not all ;-).  To see the
> problem, imagine that packCString was of type "CString  -> IO
> ByteString" (as Don suggested).  Then we still get the same weird
> behavior if we replace:
> let s = packCString x
> with
> s <- packCString x
> in the example that I posted.
> 
> The problem is that 'x' allows us to mutate the memory area occupied
> by s' but Haskell values are supposed to be immutable.  So if we want
> to have these functions, then it seems that the best we can do is to
> mark them with the "unsafe" label and be very careful how we use
> them...
> 
> Out of curiosity (I have not looked at the implementation of
> ByteString) is it true that ByteStrings created in this fashion
> (i.e., with packCString) will not be garbage collected?
> 

    packCString :: CString -> IO ByteString
    packCString cstr = do
        fp <- newForeignPtr_ (castPtr cstr)
        l <- c_strlen cstr
        return $! PS fp 0 (fromIntegral l)

The string is managed on the CString side. So however that CString is
managed (maybe its on the Haskell heap, maybe its on the C side, maybe
malloc looks after it).

As indicated in the my api post, copyCString will be the default after
today, which will just produce a normal Haskell value. unsafePackCString
can then be left for those who know what they're doing.

Does that sound reasonable?

-- Don


More information about the Libraries mailing list