Type promotion in ccall arguments
simonmar at microsoft.com
Thu Mar 14 08:29:14 EST 2002
I can't remember whether this has come up before, but to my surprise
I've just discovered that FFI foreign import declarations don't contain
enough infomration to be able to determine the correct calling
convention for a given C function.
Background: recently we "fixed" a bug in GHC's native code generator
which was exposed by the following declaration:
foreign import ccall unsafe
snprintf :: CString -> CSize -> CString -> Float -> IO ()
the native code generator was passing the Float as a C float on the
stack, but snprintf() expects a double. Half-remembering that C
specifies that floats should be promoted to doubles in function call
arguemts, I modified the NCG to do just this. But the C standard
doesn't say this - it says that floats are promoted to doubles only for
(a) functions without an ANSI prototype, and
(b) vararg functions, for args after the "...".
since the NCG can't possibly know whether the function in question has a
prototype (this information isn't part of the FFI declaration), it has
to pick a calling convention to use.
Now, the reasonable thing to do is to pick the "has a prototype" calling
convention, because this will be true for most libraries. But in the
snprintf case above, the Haskell programmer would still have to
explicitly declare the argument type to be a Double. I think something
to this effect should be included in the FFI spec.
More information about the FFI