
#11836: Hello World Bug - silent stdout errors -------------------------------------+------------------------------------- Reporter: bit | Owner: Type: bug | Status: new Priority: normal | Milestone: Component: Compiler | Version: 7.10.3 Keywords: | Operating System: Unknown/Multiple Architecture: | Type of failure: None/Unknown Unknown/Multiple | Test Case: | Blocked By: Blocking: | Related Tickets: Differential Rev(s): | Wiki Page: -------------------------------------+------------------------------------- == Background This entertaining talk explains the issue: https://www.irill.org/events /ghm-gnu-hackers-meeting/videos/jim-meyering-goodbye-world-the-perils-of- relying-on-output-streams-in-c == hello.hs {{{#!hs main = putStrLn "Hello world" }}} == Run it {{{ $ runhaskell hello.hs > /dev/full ; echo $? hello.hs: <stdout>: hPutChar: resource exhausted (No space left on device) 1 }}} That looks good! We tried to save the output to a file but the disk was full, so we got an error message, and a process exit code indicating failure. == Run it compiled {{{ $ ghc hello.hs $ ./hello > /dev/full ; echo $? 0 }}} Not good! The error was silently ignored, and additionally the process lied when it reported a successful exit status. Why did it behave differently when compiled? When `runhaskell` is used, the buffering of stdout is `NoBuffering` therefore the putStrLn call fails. But when compiled, stdout is in `LineBuffering` mode and therefore the putStrLn call succeeds. The fix: == hello2.hs {{{#!hs import System.IO main = do putStrLn "Hello world" hClose stdout }}} == Run it compiled {{{ $ ghc hello2.hs $ ./hello2 > /dev/full ; echo $? hello: <stdout>: hClose: resource exhausted (No space left on device) 1 }}} Looks good! But there's a catch: {{{ $ runhaskell hello2.hs ; echo $? Hello world ghc: <stdout>: hFlush: illegal operation (handle is closed) 1 }}} Now our program fails to run correctly with `runhaskell` :( It seems that `runhaskell` is running some hidden code after main finished. It is not clear to me how to write a correct "Hello World" that works both compiled and with `runhaskell`. == Summary One of the greatest things about Haskell is that short, clear and concise programs can also be correct. It is my opinion that the original "hello.hs" should Just Workâ˘. Haskell programmers shouldn't have to know that they need to always close stdout before exiting. Especially since it's not even clear how to do it properly... Thank you! -- Ticket URL: http://ghc.haskell.org/trac/ghc/ticket/11836 GHC http://www.haskell.org/ghc/ The Glasgow Haskell Compiler