
iavor.diatchki:
Hello,
On 1/28/07, Duncan Coutts
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