Opened 3 years ago

Closed 2 years ago

#8650 closed bug (invalid)

Unexpected behaviour of import ccall "header.h function"

Reported by: nh2 Owned by:
Priority: normal Milestone:
Component: Compiler Version: 7.6.3
Keywords: Cc: mail@…
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: Documentation bug Test Case:
Blocked By: Blocking:
Related Tickets: Differential Rev(s):
Wiki Page:

Description

When I write

foreign import ccall "myheader.h myfunction" function :: IO ...

Is GHC supposed to check the existence of the header file, or do anything with it?

Because I can still write "myheaderBLA.h myfunction" and it doesn't care about the first word (no error, ever, not even in linking, executable builds all fine).


Relatedly, I can write

foreign import ccall "some.rubbish" f :: IO ...

and as long as "some.rubbish" contains a dot, nothin in the system will ever complain.

carter suggested that maybe names with a dot inside are ignored by a linker.

This leads me to the question: In my example above, is myheaderBLA.h actually understood as some kind of file and ignored by e.g. GHC, or is it a garbled symbol name? In that case, why does http://www.haskell.org/onlinereport/haskell2010/haskellch8.html suggest ccall "string.h strlen"? In the other case, why would it suggest this if the "string.h" part is ignored?

Change History (4)

comment:1 Changed 3 years ago by carter

so does ghc currently not check if the header file is visible among the enumerated include dirs when compiling the ffi binding?

comment:2 Changed 3 years ago by thomie

From Section 8.5.1 of the report (emphasis mine):

The optional filename chname specifies a C header file, where the intended meaning is that the header file declares the C entity identified by cid.

From the GHC user's guide:

C functions are normally declared using prototypes in a C header file. Earlier versions of GHC (6.8.3 and earlier) #included the header file in the C source file generated from the Haskell code, and the C compiler could therefore check that the C function being called via the FFI was being called at the right type.

GHC no longer includes external header files when compiling via C, so this checking is not performed.

comment:3 Changed 3 years ago by carter

huh, so ghc no longer provides that validation because we no longer do f-via-c by default?

comment:4 in reply to:  description Changed 2 years ago by rwbarton

Resolution: invalid
Status: newclosed

Basically, by providing the correct header file in the import specification, you gain portability to Haskell compilers which compile via C (including, but not limited to, ancient or unregisterised versions of GHC).

Replying to nh2:

In that case, why does http://www.haskell.org/onlinereport/haskell2010/haskellch8.html suggest ccall "string.h strlen"? In the other case, why would it suggest this if the "string.h" part is ignored?

Because that is the Haskell 2010 Report, not the GHC documentation (though it would be accurate for unregisterised versions of GHC).

Relatedly, I can write

foreign import ccall "some.rubbish" f :: IO ...

and as long as "some.rubbish" contains a dot, nothin in the system will ever complain.

As specified by section 8.5.1 of the Report, both the chname and the cid are optional. The Report does not specify how to resolve the resulting ambiguity, but since a C identifier cannot contain a dot, GHC must be treating some.rubbish as the header file name, and using the Haskell name f as the C identifier, as also specified by the Report:

If cid is omitted, it defaults to the name of the imported Haskell variable.

Note: See TracTickets for help on using tickets.