Next: , Up: Data passing conventions   [Contents]


15.3.1 C data passing conventions

The Mercury primitive types are mapped to the following C types:

Mercury typeC type
intMR_Integer
int8int8_t
int16int16_t
int32int32_t
int64int64_t
uintMR_Unsigned
uint8uint8_t
uint16uint16_t
uint32uint32_t
uint64uint64_t
floatMR_Float
charMR_Char
stringMR_String

In the current implementation, MR_Integer is a typedef for a signed integral type which is the same size as a pointer of type ‘void *’; MR_Unsigned is a typedef for an unsigned integral type which is the same size as a pointer of type ‘void *’; MR_Float is a typedef for double (unless the program and the Mercury library was compiled with ‘--single-prec-float’, in which case it is a typedef for float); MR_Char is a typedef for a signed 32-bit integral type and MR_String is a typedef for ‘char *’.

Mercury variables of primitive types are passed to and from C as C variables of the corresponding C type.

For the Mercury standard library type ‘bool.bool’, there is a corresponding C type, MR_Bool. C code can refer to the boolean data constructors ‘yes’ and ‘no’, as MR_YES and MR_NO respectively.

For the Mercury standard library type ‘builtin.comparison_result’, there is a corresponding C type, MR_Comparison_Result. C code can refer to the data constructors of this type, ‘(<)’, ‘(=)’ and ‘(>)’, as MR_COMPARE_LESS, MR_COMPARE_EQUAL and MR_COMPARE_GREATER respectively.

Mercury variables of a type for which there is a C ‘pragma foreign_type’ declaration (see Using foreign types from Mercury) will be passed as the corresponding C type.

Mercury tuple types are passed as MR_Tuple, which in the current implementation is a typedef for a pointer of type ‘void *’ if ‘--high-level-code’ is enabled, and a typedef for MR_Word otherwise.

Mercury variables of any other type are passed as a MR_Word, which in the current implementation is a typedef for an unsigned type whose size is the same size as a pointer. (Note: it would in fact be better for each Mercury type to map to a distinct abstract type in C, since that would be more type-safe, and thus we may change this in a future release. We advise programmers who are manipulating Mercury types in C code to use typedefs for each user-defined Mercury type, and to treat each such type as an abstract data type. This is good style and it will also minimize any compatibility problems if and when we do change this.)

Mercury lists can be manipulated by C code using the following macros, which are defined by the Mercury implementation.

MR_list_is_empty(list)     /* test if a list is empty */
MR_list_head(list)         /* get the head of a list */
MR_list_tail(list)         /* get the tail of a list */
MR_list_empty()            /* create an empty list */
MR_list_cons(head,tail)    /* construct a list with the given head and tail */

Note that the use of these macros is subject to some caveats (see Memory management for C).

The implementation provides the macro MR_word_to_float for converting a value of type MR_Word to one of type MR_Float, and the macro MR_float_to_word for converting a value of type MR_Float to one of type MR_Word. These macros must be used to perform these conversions since for some Mercury implementations ‘sizeof(MR_Float)’ is greater than ‘sizeof(MR_Word)’.

The following fragment of C code illustrates the correct way to extract the head of a Mercury list of floats.

MR_Float f;
f = MR_word_to_float(MR_list_head(list));

Omitting the call to MR_word_to_float in the above example would yield incorrect results for implementations where ‘sizeof(MR_Float)’ is greater than ‘sizeof(MR_Word)’.

Similarly, the implementation provides the macros MR_word_to_int64 and MR_word_to_uint64 for converting values of type MR_Word to ones of type int64_t or uint64_t respectively, and the macros MR_int64_to_word and MR_uint64_to_word for converting values of type int64_t or uint64_t respectively to ones of type MR_Word. These macros must be used to perform these conversions since for some Mercury implementations ‘sizeof(int64_t)’ or ‘sizeof(uint64_t)’ are greater than ‘sizeof(MR_Word)’.


Next: , Up: Data passing conventions   [Contents]