#2583: printf %s is not lazy enough
------------------------+---------------------------------------------------
    Reporter:  olsner   |       Owner:                
        Type:  bug      |      Status:  new           
    Priority:  normal   |   Component:  libraries/base
     Version:  6.8.3    |    Severity:  minor         
    Keywords:           |    Testcase:                
Architecture:  Unknown  |          Os:  Unknown       
------------------------+---------------------------------------------------
 Taking a fixpoint of printf {{{fix (printf "a%s") :: String}}}, or
 printf'ing an infinite string {{{printf "%s" (repeat ' ') :: String}}}
 either fails with stack overflow or diverges.

 The culprit is in this code:
 {{{
 fmt cs us =
         let (width, prec, ladj, zero, plus, cs', us') = getSpecs False
 False False cs us
             adjust (pre, str) =
                 let lstr = length str
                     lpre = length pre
                     fill = if lstr+lpre < width then take
 (width-(lstr+lpre)) (repeat (if zero then '0' else ' ')) else ""
                 in  if ladj then pre ++ str ++ fill else if zero then pre
 ++ fill ++ str else fill ++ pre ++ str
 }}}

 If width == 0, then no filling should be done, but the code is still
 forcing the evaluation of lstr and lpre (which in the case of an infinite
 str does not ever complete). A simple fix is to check that width is larger
 than zero before trying to test width against lstr and lpre, like this:

 {{{
 fill = if width > 0 && lstr+lpre < width then {-etc-}
 }}}

-- 
Ticket URL: <http://hackage.haskell.org/trac/ghc/ticket/2583>
GHC <http://www.haskell.org/ghc/>
The Glasgow Haskell Compiler
_______________________________________________
Glasgow-haskell-bugs mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to