From 3aca3f915d2edc71a8633181577258f04996e42a Mon Sep 17 00:00:00 2001 From: simonpj Date: Wed, 11 Sep 2002 11:06:05 +0000 Subject: [PATCH] [project @ 2002-09-11 11:06:05 by simonpj] Add documentation about unsafePerformIO --- GHC/IOBase.lhs | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/GHC/IOBase.lhs b/GHC/IOBase.lhs index 5f84206..60ae45b 100644 --- a/GHC/IOBase.lhs +++ b/GHC/IOBase.lhs @@ -131,9 +131,31 @@ free of side effects and independent of its environment. If the I\/O computation wrapped in 'unsafePerformIO' performs side effects, then the relative order in which those side effects take place (relative to the main I\/O trunk, or other calls to -'unsafePerformIO') is indeterminate. - -However, it is less well known that +'unsafePerformIO') is indeterminate. You have to be careful when +writing and compiling modules that use 'unsafePerformIO': + * Use @{-# NOINLINE foo #-}@ as a pragma on any function @foo@ + that calls 'unsafePerformIO'. If the call is inlined, + the I/O may be performed more than once. + + * Use the compiler flag @-fno-cse@ to prevent common sub-expression + elimination being performed on the module, which might combine + two side effects that were meant to be separate. A good example + is using multiple global variables (like @test@ in the example below). + + * Make sure that the either you switch off let-floating, or that the + call to 'unsafePerformIO' cannot float outside a lambda. For example, + if you say: + @ + f x = unsafePerformIO (newIORef []) + @ + you may get only one reference cell shared between all calls to @f@. + Better would be + @ + f x = unsafePerformIO (newIORef [x]) + @ + because now it can't float outside the lambda. + +It is less well known that 'unsafePerformIO' is not type safe. For example: > test :: IORef [a] -- 1.7.10.4