
Duncan Coutts wrote:
On Tue, 2006-03-28 at 01:37 +0100, Brian Hulley wrote:
Hi Duncan - I just declared duma_vertex3f (in another module) by:
foreign import ccall duma_vertex3f :: Float -> Float -> Float -> IO ()
I thought this means that the C function prototype must be:
void duma_vertex3f(HsFloat, HsFloat, HsFloat);
so I don't understand why GHC (or any other Haskell compiler) would ever need to see a C header file to generate the correct code. What info could be in the header that is not already in the Haskell type?
Because ghc does compile via C and does use the C header files to get the C function prototype. Well it can compile via C and it's recommended when compiling FFI code since it allows the Haskell type you've declared to be checked against the C prototype.
The warning you saw was coming from gcc as it compiled the C code emitted by ghc.
So it's mostly as a sanity check but actually there is some information in the C prototype that is not reflected in the Haskell type. For example 'const'ness, which is why you might sometimes see warnings from gcc about casting away the const attribute. More seriously there is the single/double issue. In the absence of a prototype C will promote single to double. If the function really was declared as single then using double will probably cause a crash. There are probably other examples where not using a C prototype can lead to trouble.
There are more probably details on this issue in the emails during the FFI standardisation process.
Also the User's Guide has a snippet about it: http://www.haskell.org/ghc/docs/latest/html/users_guide/sec-ffi-ghc.html#gla... and this FAQ entry: http://haskell.org/haskellwiki/GHC/FAQ#When_I_use_a_foreign_function_that_ta.... Cheers, Simon