Generating Function Prototypes

Alastair Reid reid at reid-consulting-uk.ltd.uk
Thu Jul 4 18:23:32 EDT 2002


Simon:
> Whether a header file is supplied or not should not affect the
> semantics of the call (I'm pretty sure you agree with this, but we
> seem to have lost track of this central concept somewhere along the
> way...). 

I absolutely agree that the ffi design _should_ not allow it to affect
it.  As I understand it, the current ffi specification/ design _does_
allow it to affect it.

> Similarly, whether there is a prototype in scope or not
> should not affect the semantics of the call.  The FFI spec doesn't
> say this explicitly, but I don't think it needs to.

Yes If that is the intention, then it should say so explicitly.
And if that is not the intention then it should say that.

What I believe I'm hearing from Manuel is that the presence of
function prototypes is allowed to affect code generation.  This is
what ghc -fvia-C does but (by implication) not what GHC's native code
generator does.  Even within a single compiler we find both
interpretations of the ffi spec...

Alastair:
>> [...] the second example needs a header file to compile correctly
>> with GHC.

> Only when -fvia-C is on.  This is a compiler-specific issue, the FFI
> doesn't need to say anything about it.

The ffi spec should be clear about whether GHC (and Hugs and NHC) is
allowed to ignore the header file, required to obey the header file or
free to do one thing or another.

>> When a header file containing a function prototype is not provided,
>> the function calling convention employed is undefined.  It may vary
>> between different operating systems, between different Haskell
>> compilers, and between different functions.

> This is exactly what we *don't* want - the semantics should be
> specified by the FFI declaration alone, independent of any header
> files.  Again, I'm sure you agree with this - but why do you think
> that supplying a header file should make a difference to the
> semantics?

I agree that it is undesirable but I think that it currently _does_
make a difference to the semantics.  I'd much rather have a spec where
its presence doesn't matter but failing that I'd like a spec which
is clear about what you need to do to write portable code.

>> Note that I am trying to make it quite clear that an ffi
>> declaration is not portable unless you provide function prototypes
>> except in the special case that your C compiler generates the same
>> code with or without a prototype.

> I really don't think the FFI spec needs to say anything about this
> at all.  If a particular compiler requires prototypes in order to
> generate correct code (such as GHC when going via C) then this is a
> matter for that compiler's documentation.  Indeed, the GHC User's
> Guide does mention this.

As someone who wants to be able to write portable ffi code (actually,
I want to be able to steal ffi code originally written for GHC :-), I
need to know what ffi code is portable and what is not.  I have
attempted to describe what is currently portable between the different
implementations.  I believe it is the job of the ffi to be clear about
what it can guarantee and what it cannot.

> [ Heh.  Now I remember why I didn't like being able to specify
> header files in the FFI declaration :-) ]

I don't especially like it either - much better to specify it on the
compiler command line just as it's better to specify libraries on the
command line.

Some obvious problems: Suppose a single .hs file contains foreign
imports which #include two different header files.  Are those header
files allowed to have conflicting definitions?  What if a foreign
import is inlined into another module and it then conflicts with a
foreign import in that module.  Is it enough for just one foreign
import in the file to mention a header file?  What about multiple
includes of the same file?  Is the header file required to use some
form of multi-include protection?

These all stem from the same problem as library specs - pretending
that each header file/ library lives in its own personal namespace
when there is a single global namespace.

>> ps I still think we're better off removing header files completely
>> and having the Haskell type completely determine the calling
>> convention employed.  But since I'm not getting any takers on that,
>> I'll settle for pinning down the spec as tightly as possible.

> Aha!

> I must have lost track of the discussion because I can't remember at
> which point someone said that the Haskell type does not completely
> specify the calling convention.

If specifying a header file with a function prototype is allowed to
affect the generated code (i.e., the calling convention), then it is
clear that the Haskell type does not completely determine the calling
convention. 

And if it does not, let's remove header files from the spec.

--
Alastair



More information about the FFI mailing list