scope of header files
Duncan Coutts
duncan.coutts at worc.ox.ac.uk
Wed Mar 12 22:18:48 EDT 2008
On Tue, 2008-03-11 at 16:25 -0700, Simon Marlow wrote:
> Duncan Coutts wrote:
> > from:
> > http://hackage.haskell.org/cgi-bin/hackage-scripts/package/mage-1.0
> >
> > perhapsPbecause it's a pointer import it gets treated differently?
>
> I just tried this and couldn't reproduce the problem.
> Maybe there's something else going on.. can you boil down the example at
> all?
I can reproduce the problem with the mage-1.0 tarball with the following
changes:
add -fvia-C to the ghc-options
add include-dirs: src
Inspecting Main.hc we find things like:
_s2oT = *((P_)(W_)&stdscr);
that is references to the stdscr pointer.
I was trying to get a boiled down example. I started with src/Main and
commented stuff out. By commenting out the call to clear_screen the
error went away. That's because it's clear_screen from src/Curses.hsc
that references stdscrp.
I swear it's non-deterministic, even when removing the .hi files before
each run.
Here's the smallest I can get it:
module Curses (screen_size) where
import Foreign
data WINDOW = WINDOW
type WINDOWptr = Ptr WINDOW
foreign import ccall unsafe "curses.h & stdscr" stdscrp :: Ptr WINDOWptr
screen_size :: IO ()
screen_size = do
stdscr <- peek stdscrp
return ()
module Main (main) where
import Curses
main = print =<< screen_size
And (re-)building using:
$ rm Main.hi Curses.hi; ghc-6.8.2 --make -O2 -fvia-C -fffi Main.hs
-keep-hc-files
[1 of 2] Compiling Curses ( Curses.hs, Curses.o )
[2 of 2] Compiling Main ( Main.hs, Main.o )
In file included from /usr/lib64/ghc-6.8.2/include/Stg.h:150,
from Main.hc:3:0:
Main.hc: In function ‘Main_a_entry’:
Main.hc:46:0:
error: ‘stdscr’ undeclared (first use in this function)
Main.hc:46:0:
error: (Each undeclared identifier is reported only once
Main.hc:46:0: error: for each function it appears in.)
Inspecting Main.hc we see
_sFH = *((P_)(W_)&stdscr);
inside the Main_a_entry.
The Curses.hc does #include "curses.h" as required. It's Main.hc that
does not, despite using &stdscr.
Seems that -O2 is not necessary, -O also elicits the failure.
ghc --show-iface Curses.hi shows us these interesting exports:
screen_size :: GHC.IOBase.IO ()
{- Arity: 1 HasNoCafRefs Strictness: L
Unfolding: (Curses.a `cast` (sym ((GHC.IOBase.:CoIO) ()))) -}
a :: GHC.Prim.State# GHC.Prim.RealWorld
-> (# GHC.Prim.State# GHC.Prim.RealWorld, () #)
{- Arity: 1 HasNoCafRefs Strictness: L
Unfolding: (\ s :: GHC.Prim.State# GHC.Prim.RealWorld ->
case @ (# GHC.Prim.State# GHC.Prim.RealWorld, () #)
GHC.Prim.readAddrOffAddr#
@ GHC.Prim.RealWorld
__label "stdscr"
0
s of wild2 { (# s2, x #) ->
(# s2, GHC.Base.() #) }) -}
(re-indented to fit)
The __label "stdscr" in a's unfolding is particularly interesting. That
looks like the route by which "stdscr" escapes the Curses module and
ends up in Main, outside of the scope of the header file.
Duncan
More information about the Glasgow-haskell-users
mailing list