Where can I learn about #ifdef?

2019-02-02 20:07发布

问题:

I see this used often to make modules compatible with GHC and Hugs, but google is not helping me learn more about it.

What can I put inside the conditional? Can I make parts of a module conditional on what version of 'base' is in use?

EDIT 3/2017: This is a great resource: https://guide.aelve.com/haskell/cpp-vww0qd72

回答1:

The GHC documentation has a section relating to the C pre-processor that documents some of the predefined pre-processor macros.

The Cabal documentation has a section relating to conditional compilation that gives an example relating to base. If you are writing a portable package, you should be using Cabal, anyway.



回答2:

In addition to the very useful flags defined by GHC (OS, architecture, etc), when using cabal other flags and macros are defined.

Check Package Versions

Here's a use from crypto-api that checks the version of the tagged package being used:

#if MIN_VERSION_tagged(0,2,0)
import Data.Proxy
#endif

Custom CPP Defines Based on Cabal Flags

You can define CPP symbols dependent on cabal flags. Here's an (unnecessarily complex) example from pureMD5 (from the .cabal file):

 if arch(i386) || arch(x86_64)
   cpp-options: -DFastWordExtract

Inside the .hs module you can then use #ifdef, for example:

#ifdef FastWordExtract
getNthWord n b = inlinePerformIO (unsafeUseAsCString b (flip peekElemOff n . castPtr))
#else
... other code ...
#endif

For more information you can see the Cabal users guide. This page has the "conditional compilation" information you're probably looking for.



回答3:

#ifdef and friends are used by the C preprocessor (CPP). They provide a way to compile code conditionally. You can enable the use of the CPP by adding the pragma {-# LANGUAGE CPP #-} on top of a file.

Many programs that deal with Haskell code set some macros for the preprocessor (eg. GHC sets __GLASGOW_HASKELL__ to the version of GHC), so one can conditionally compile code, for instance to use different properitary libraries for Hugs and GHC.



回答4:

If you run your Haskell compiler with the -cpp option, it will first preprocess the source files with the CPP (C Pre Processor).

Take a look at the section 4.11.3. Options affecting the C pre-processor here.