macros expanding into preprocessor directives violates C standard? #33

wants to merge 1 commit into


None yet

4 participants


The macros ALEX_IF.., ALEX_ENDIF, ALEX_ELIF etc cause failures using alex using GCC 4.2. I'm not sure if this is an actual issue with alex, or an issue using gcc 4.2.

This patch removes the macros that expand to preprocessor directives.

I suspect this is an issue with alex because of 1973 in of the C0x spec. The same section has a similar restriction for C99.

"The resulting completely macro-replaced preprocessing token sequence is not processed as a preprocessing directive even if it resembles one[...]"

EG: The "resulting" sequence this is referring to is, AFAIK, would be the "#if GLASGOW_HASKELL > 500" for the ALEX_IF_GHC_GT_500 macro.

An example failure when building yi:

Preprocessing library yi-0.7.0...

src/library/Yi/Core.hs:2:14: Warning:
    -XDoRec is deprecated: use -XRecursiveDo or pragma {-# LANGUAGE RecursiveDo #-} instead
line-map.c: file "templates/GenericTemplate.hs" left but not entered

dist/build/Yi/Lexer/Abella.hs:130:0:  error: #else without #if

dist/build/Yi/Lexer/Abella.hs:131:0:  warning: "GTE" redefined

     warning: this is the location of the previous definition

dist/build/Yi/Lexer/Abella.hs:132:0:  warning: "EQ" redefined

     warning: this is the location of the previous definition

dist/build/Yi/Lexer/Abella.hs:133:0:  error: #endif without #if

dist/build/Yi/Lexer/Abella.hs:184:0:  error: #else without #if

dist/build/Yi/Lexer/Abella.hs:187:0:  error: #endif without #if
@coreyoconnor coreyoconnor The expansion of macros into preprocessor directives appears to viola…
…te the C standard for macro

Specifically 1973 in of the C0x spec. The same section has a similar restriction for C99.

This breaks compiling 7.8.
Closing for now.


The particular error when compiling GHC is:

    Couldn't match expected type ‛Bool’ with actual type ‛Int#’
    In the first argument of ‛(&&)’, namely ‛(offset >=# 0#)’
    In the expression: (offset >=# 0#) && (check ==# ord_c)
    In the expression:
      if (offset >=# 0#) && (check ==# ord_c) then
          alexIndexInt16OffAddr alex_table offset
          alexIndexInt16OffAddr alex_deflt s

Which appears due to the undefining of GLASGOW_HASKELL. Which is not removed by this patch.


The extra layer of macros is necessary. See simonmar/happy#9.

dist/build/Yi/Lexer/Abella.hs:130:0: error: #else without #if

Can you show the generated code near this #else? Especially line 127, which is supposed to be

#if __GLASGOW_HASKELL__ > 706

Happy and alex both have similar template preprocessing? Both have a GenericTemplate.hs which is expected to be preprocessed twice?

The below is using happy, but assuming they are similar:

When I try to compile haskell-src-exts-1.14.0 the compilation fails with:

[16 of 16] Compiling Language.Haskell.Exts.InternalParser ( dist/build/Language/Haskell/Exts/InternalParser.hs, interpreted )

<built-in>:2:2: Not in scope: ‛#’

examining the happy preprocessed InternalParser.hs: dist/build/Language/Haskell/Exts/InternalParser.hs:

# 1 "<built-in>" 1
# 1 "templates/GenericTemplate.hs" 2
-- Id: GenericTemplate.hs,v 1.26 2005/01/14 14:47:22 simonmar Exp

{-# LINE 13 "templates/GenericTemplate.hs" #-}

 #if __GLASGOW_HASKELL__ > 706
#define LT(n,m) ((Happy_GHC_Exts.tagToEnum# (n Happy_GHC_Exts.<# m)) :: Bool)
#define GTE(n,m) ((Happy_GHC_Exts.tagToEnum# (n Happy_GHC_Exts.>=# m)) :: Bool)
#define EQ(n,m) ((Happy_GHC_Exts.tagToEnum# (n Happy_GHC_Exts.==# m)) :: Bool)
#define LT(n,m) (n Happy_GHC_Exts.<# m)
#define GTE(n,m) (n Happy_GHC_Exts.>=# m)
#define EQ(n,m) (n Happy_GHC_Exts.==# m)

(github's editor is making this very difficult)
The only odd part, IMO, is the extra space before "#if". This is what I thought was responsible for the error, but does not actually appear to be the case. I have no idea where the compile failure is coming from.


Please try with the Happy 1.19.1 in case that fixes it (probably not). What platform, GHC version, etc?


This is on GHC HEAD (7.7.20131031). The platform is Mac 10.8.5 using XCode 5 command line tools. Which, IIRC, means GHC is using clang's preprocessor.

This looks to be the same as:

I think moving this discussion to that trac ticket would be best. Agreed?


@coreyoconnor the issue in the trac ticket is even with using GCC's CPP. The problem is the leading white space i think...


I've tried removing the leading whitespace from teh preprocessed file then loading the file in GHCI. This still results in ":2:2: Not in scope: ‛#’"

I'm not 100% confident my test was correct. There could have been another leading whitespace I was missing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment