ndmitchell / cmdargs

Haskell library for command line argument processing
Other
91 stars 12 forks source link

Different (non-working) output with ghc -O (ghc 7.8.3) #13

Open ipuustin opened 10 years ago

ipuustin commented 10 years ago

Hi,

When I compile a modal application with optimizations on (such as is done by default with cabal), the command line parsing doesn't work as expected. Here's a small example program:

{-# LANGUAGE DeriveDataTypeable #-}

module Main
where
import System.Console.CmdArgs

data ProgramMode = Mode1 {
                common :: String,
                private1 :: String
            }
            | Mode2 {
                common :: String,
                private2 :: String
            } deriving (Show, Data, Typeable)

mode1 :: ProgramMode
mode1 = Mode1
    {
        private1 = def,
        common = def &= argPos 0
    }

mode2 :: ProgramMode
mode2 = Mode2
    {
        private2 = def,
        common = def &= argPos 0
    }

main :: IO ()
main = do
    let m = modes [mode1, mode2]
    parsedArgs <- cmdArgs m
    print parsedArgs

This is what should happen, compiled with ghc --make Main.hs:

[ipuustin@ipuustin-mobl1 cmdargs]$ ./Main -?
The programmode program

programmode [COMMAND] ... [OPTIONS]

Common flags:
  -? --help           Display help message
  -V --version        Print version information

programmode mode1 [OPTIONS] ITEM

  -p --private1=ITEM

programmode mode2 [OPTIONS] ITEM

  -p --private2=ITEM

This is the error case when the second mode doesn't work, compiled with ghc --make -O Main.hs:

[ipuustin@ipuustin-mobl1 cmdargs]$ ./Main -?
The programmode program

 programmode [COMMAND] ... [OPTIONS]

Common flags:
  -? --help           Display help message
  -V --version        Print version information

programmode mode1 [OPTIONS] ITEM

  -p --private1=ITEM

programmode mode2 [OPTIONS]

  -c --common=ITEM  
  -p --private2=ITEM

I'm using GHC 7.8.3:

[ipuustin@ipuustin-mobl1 cmdargs]$ ghc -V
The Glorious Glasgow Haskell Compilation System, version 7.8.3
ndmitchell commented 10 years ago

I think you need to add the following to the module which defines mode1 and mode2:

{-# OPTIONS_GHC -fno-cse #-}

That should fix it. Alternatively, you can omit the common definition in mode2 and it will automatically follow the definition in mode1. Unfortunately CmdArgs is a bit impure when constructing the record, and the CSE that GHC does breaks things. You can read a more complete explanation (in the docs)[http://hackage.haskell.org/package/cmdargs/docs/System-Console-CmdArgs-Implicit.html]. Does that fix it for you?

ipuustin commented 10 years ago

Yes, this fixed it. I missed (or didn't parse) the shared annotation part in the docs. Thanks! Closing the issue.

ndmitchell commented 10 years ago

I've just checked. I have some stuff that makes CSE less likely to happen, which works fine in GHC 7.6, but has broken in 7.8. I'll see if I can fix it.

orlitzky commented 10 years ago

"me too"

The second mode of http://hackage.haskell.org/package/haeredes is affected by this, but it can be built with -fno-cse as a workaround.