Unsafe aspects of ByteString

Stefan O'Rear stefanor at cox.net
Sun Jan 28 14:28:51 EST 2007


On Sun, Jan 28, 2007 at 07:16:16PM +0000, Chris Kuklewicz wrote:
> Iavor Diatchki wrote:
> > Hello,
> > The "packCString" function (and other similar functions) in the
> > ByteString library break referential transperancy, which is one of the
> > big selling points of Haskell (and its libraries).   Here is an
> > example:
> > 
> > main = do x <- newCString "Hello"
> >          let s   = packCString x
> >              h1  = B.head s
> >          print s
> >          -- print h1
> >          poke x (toEnum 97)
> >          print s
> >          let h2 = B.head s
> >          print h1
> >          print h2
> > Output:
> > "Hello"
> > "aello"
> > 97
> > 97
> > 
> > This is already confusing because the "pure" value 's' has magically
> > changed.   Also notice that the evaluation order of the program
> > affects the output.  If we include the commented out statement (which
> > forces h1 to be evaluated earlier) the output becomes:
> > "Hello"
> > 72
> > "aello"
> > 72
> > 97

It gets more fun:

import Foreign.C.String
import Data.ByteString
import Control.Exception

shouldBePure :: CString -> ()
shouldBePure str = packMallocCString str `seq` ()

main = do x <- newCString "Hello"
          evaluate $ shouldBePure x
          evaluate $ shouldBePure x
          -- force a GC
          evaluate $ Prelude.reverse [0..]

-->

stefan at stefans:/tmp$ ./X
*** glibc detected *** double free or corruption (fasttop): 0x08086628 ***
Aborted

Now what if GHC did more CSE... <shudder>


More information about the Libraries mailing list