Unsafe aspects of ByteString

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

> dons at cse.unsw.edu.au wrote:
> > The functions should document this behaviour better. Of course, you're
> paying with poke and C strings so you
> > should be careful anyway. I'll correct the documentation to explain
> all this.
> Forgive a non-experts comment:
> This approach ("read the doco and be careful when you use these
> functions") feels contrary to the haskell ethos of pure code being
> reliably pure. What's the argument for not prefixing such functions with
> "unsafe"? 

No no. The types should certainly reflect the safety. And by default
people should try the safe versions :) Its a tricy area to get exactly
right, since we're straddling the C / Haskell interface here.

* The current api:

    Zero-copying, efficient. Unsafe if you mutate the C string, in the
    case of packMallocCString, if you run the finalisers twice:

        packCString         :: CString -> ByteString
        packCStringLen      :: CStringLen -> ByteString
        packMallocCString   :: CString -> ByteString
        useAsCStringLen     :: ByteString -> (CStringLen -> IO a) -> IO a

    Safe. Copies the ByteString:

        copyCString         :: CString -> IO ByteString
        copyCStringLen      :: CStringLen -> IO ByteString
        useAsCString        :: ByteString -> (CString -> IO a) -> IO a

* The proposed api:

The following will be safe, copying across the C/Haskell boundary by default:

    packCString             :: CString    -> IO ByteString
    packCStringLen          :: CStringLen -> IO ByteString
    packMallocCString       :: CString    -> IO ByteString
    useAsCString            :: ByteString -> (CString -> IO a) -> IO a
    useAsCStringLen         :: ByteString -> (CStringLen -> IO a) -> IO a

Those with extra efficiency needs, but also extra safety requirements:

    unsafePackCString             :: CString    -> IO ByteString
    unsafePackCStringLen          :: CStringLen -> IO ByteString
    unsafePackMallocCString       :: CString    -> IO ByteString
    unsafeUseAsCString            :: ByteString -> (CString -> IO a) -> IO a
    unsafeUseAsCStringLen         :: ByteString -> (CStringLen -> IO a) -> IO a

Which will all do zero-copying calls acroos into C (or Haskell), but
you'll need to ensure you don't mutate the C string.

The safety requirements for the unsafe* versions will be clearly stated.

-- Don

More information about the Libraries mailing list