CPP Directives and Inline C Code

The Binding Generator C->Haskell : Implementation of Haskell Binding Modules : CPP Directives and Inline C Code
Previous: Class Hooks
Next: Grammar Rules

## 2.12. CPP Directives and Inline C Code

A Haskell binding module may include arbitrary C pre-processor directives using the standard C syntax. The directives are used in two ways: Firstly, they are included in the C header file generated by C->Haskell in exactly the same order in which they appear in the binding module. Secondly, all conditional directives are honoured by C->Haskell in that all Haskell binding code in alternatives that are discarded by the C pre-processor are also discarded by C->Haskell. This latter feature is, for example, useful to maintain different bindings for multiple versions of the same C API in a single Haskell binding module.

In addition to C pre-processor directives, vanilla C code can be maintained in a Haskell binding module by bracketing this C code with the pseudo directives `#c` and `#endc`. Such inline C code is emitted into the C header generated by C->Haskell at exactly the same position relative to CPP directives as it occurs in the binding module. Pre-processor directives may encompass the `#include` directive, which can be used instead of specifying a C header file as an argument to `c2hs`. In particular, this enables the simultaneous use of multiple header files without the need to provide a custom header file that binds them together. If a header file lib`.h` is specified as an argument to `c2hs`, the tool will emit the directive `#include"`lib`.h"` into the generated C header before any other CPP directive or inline C code.

As an artificial example of these features consider the following code:

> `

>     #define VERSION 2

>     #if (VERSION == 1)
>     foo :: CInt -> CInt
>     foo = {#call pure fooC#}
>     #else
>     foo :: CInt -> CInt -> CInt
>     foo = {#call pure fooC#}
>     #endif

>     #c
>     int fooC (int, int);
>     #endc

> `

One of two versions of the Haskell function `foo` (having different arities) is selected in dependence on the value of the CPP macro `VERSION`, which in this example is defined in the same file. In realistic code, `VERSION` would be defined in the header file supplied with the C library that is made accessible from Haskell by a binding module. The above code fragment also includes one line of inline C code that declares a C prototype for `fooC`.

Current limitation of the implementation: Inline C code can currently not contain any code blocks; i.e., only declarations as typically found in header files may be included.

The Binding Generator C->Haskell : Implementation of Haskell Binding Modules : CPP Directives and Inline C Code
Previous: Class Hooks
Next: Grammar Rules