Suppose that I have a foreign function:
-- | Turns char* of the given size into a char* of size 16.
doSomethingFfi :: Ptr CUChar -> Ptr CUChar -> CSize -> IO ()
doSomethingFfi = undefined
The function is pure, so I would like to represent it as a pure function in Haskell:
doSomething :: ByteArray bytes => bytes -> bytes
doSomething bs = unsafePerformIO $
alloc 16 $ \outPtr ->
withByteArray bs $ \inPtr ->
doSomethingFfi outPtr inPtr (fromIntegral $ length bs)
(Here I am using alloc from memory.)
My understanding is that the only difference between unsafePerformIO and unsafeDupablePerformIO is that the IO action in the latter can be silently terminated without any cleanup.
In my case above there are, essentially, two IO actions happening: 1. memory allocation; 2. foreign call. I am not concerned about 2, since it is pure, however I am worried about the memory.
Is there any guarantee that the memory allocated this way will not leak if the computation is interrupted silently? If the foreign function also required temporary storage that I had to allocate / clean up and I used alloca for this purpose, would it still be safe to use unsafeDupablePerformIO?