Opened 7 months ago

Closed 7 months ago

Last modified 7 months ago

#13440 closed bug (duplicate)

putStr doesn't have the same behavior in GHCi and after compilation with GHC

Reported by: vanto Owned by:
Priority: normal Milestone:
Component: GHCi Version: 8.0.2
Keywords: Cc:
Operating System: Windows Architecture: Unknown/Multiple
Type of failure: Other Test Case:
Blocked By: Blocking:
Related Tickets: #2189 Differential Rev(s):
Wiki Page:

Description

Hi,

main :: IO ()
main = do {
             putStr "hello";
             x <- getChar; -- or x <- getLine;
             putStr "x = ";
             print x;
           }

the program works in GHCi and after compilation with GHC. in GHCi it works fine but after compilation it does not work fine. in GHCi the first line of code is evaluated the first while after compilation is the second line which is evaluated first. so in GHCi we have as a result:

hellom
x = 'm'

and after compilation we have as a result:

m
hellox = 'm'

After compilation, putStr is not evaluated the first. It is getChar or getLine. In GHCi the behavior is correct. But after compilation the behavior is strange.

Change History (5)

comment:1 Changed 7 months ago by RyanGlScott

Are you on Windows? If so, what console are you using? I know there are several issues regarding input/output buffering which might explain the discrepancies you're seeing.

comment:2 Changed 7 months ago by vanto

for RyanGIScott
yes, I am on Windows. I use a standard Windows console (cmd.exe)
I also use Linux Debian8 under virtualBox.
I have just tested this program on Linux and here are the results.
With GHCi the result is:

*Main> main
hellomx = 'm'
*Main>

It seems much better than GHCi on Windows.
After compiling, the result is the same as Windows.

vanto@debian:~/sourcehs$./test
m
hellox = 'm'

On the other hand, I used runghc to test the program on Windows and Linux and here are the results:
with Windows
the result is the same as compilation on Windows

c:\sourcehs>runghc test.hs
m
hellox = 'm'

with Linux
the result is the same as GHCi on Windows

vanto@debian:~/sourcehs$ runghc test.hs
hellom
x = 'm'

Hope this help!

comment:3 Changed 7 months ago by vanto

On Linux I use GHC version: 8.0.2

comment:4 Changed 7 months ago by RyanGlScott

Resolution: duplicate
Status: newclosed

As it turns out, this is a duplicate of a long-standing bug in GHCi, #2189. Fixing that bug will probably require rewriting the whole IO manager to use native Win32 IO (see #11394), but luckily, someone is working on this.

Until then, I can offer you two workarounds.

  1. If you want to have a stronger guarantee that "hello" will be printed first, you can use hFlush stdout to force this:
import System.IO

main :: IO ()
main = do {
             putStr "hello";
             hFlush stdout;
             x <- getChar; -- or x <- getLine;
             putStr "x = ";
             print x;
           }
  1. Alternatively, you can try a different buffering strategy. By default, stdout's buffering mode is NoBuffering (which should, in theory, mean that all output is immediately printed to the screen, were it not for #2189). But you can change the buffering mode to something else:
import System.IO

main :: IO ()
main = do {
             hSetBuffering stdout $ BlockBuffering $ Just 1;
             putStr "hello";
             x <- getChar; -- or x <- getLine;
             putStr "x = ";
             print x;
           }

This does buffer the output, but only 1 character at a time.

I've experimentally verified that both of these workaround work on my Windows machine, on both cmd.exe and MSYS2.

comment:5 Changed 7 months ago by RyanGlScott

Component: CompilerGHCi
Operating System: Unknown/MultipleWindows
Note: See TracTickets for help on using tickets.