FFI proposal: allow some control over the scope of C header files

Duncan Coutts duncan.coutts at worc.ox.ac.uk
Fri Apr 21 10:02:57 EDT 2006

On Fri, 2006-04-21 at 09:32 -0400, Manuel M T Chakravarty wrote:

> > I think we'd want to be able to specify that a C header file not
> > "escape" a module boundary and probably we'd also want to be able to ask
> > that it not escape a package boundary (though this may be beyond the H'
> > spec since Haskell does not talk about packages).
> The H98 standard already specifies a NOINLINE pragma for any function:
>   http://haskell.org/onlinereport/pragmas.html
> The simplest solution is to ensure that all Haskell compilers implement
> this pragma properly for foreign imported functions.  If you want finer
> control over where inlining takes place, then maybe the pragma should be
> extended to provide that finer control.

I don't think we need to generalise the problem to all function
inlinings. There are specific practical problems caused by inlining
foreign calls that are not a problem for ordinary Haskell functions.

> Besides, the standard so far doesn't cover command line options at all.
> So, there is the more general question of whether it should.

I don't think we need to specify the command line interface. The
required headers can be put in the module.

> > So some syntax off the top of my head:
> > 
> > foreign import cheader module-local "foo/bar.h"
> > 
> > I think there are 3 possibilities for the C header escape/scope setting
> > (which should probably be manditory rather than optional):
> > module-local
> > package-local (extension for compilers that have a notion of a package)
> > global
> Is this additional complexity really necessary or would the use of
> NOINLINE pragmas not suffice?  It's really in a library context where
> you want to restrict the inlining of foreign functions, but there the
> foreign functions are probably not much used inside the library itself,
> but mainly exported, so I doubt that you would get much of a performance
> loss by just tagging all foreign imported functions that you don't want
> to escape as NOINLINE.

What I really want is for the issue of header scope to be something that
can be checked by the compiler. As a distro packager I see far too many
people getting it wrong because they don't understand the issue. If we
could declare the intended scope of the header files then 1. people
would think about and 2. if they got it wrong it'd be checkable because
the compiler would complain.

As it is at the moment people don't know they're doing anything dodgy
until some user of their package gets a mysterious gcc warning and
possibly a segfault.

If we just tell everyone that they should use NOINLINE then they won't
and they'll still get it wrong.

The reason for some specific syntax rather than using NOINLINE is that
the compiler will be able to track the header files needed by each
module. So we can avoid the situation where a call gets made outside the
scope of its defining header file - either by automatically #including
the header file in the right place, or by complaining if the user does
not supply the header (eg by putting it in the .cabal file).

So it's not the general issue of inlining but the specific problem of
what C header files are required to compile what modules.

The ideal situation I imagine is that the scope of the headers can be
checked automatically so that the compiler or cabal will complain to a
library author that their private header file needs to be marked as
local to the package/module or included in the library package file and
installed with the package.


More information about the Haskell-prime mailing list