Next: C# data passing conventions, Up: Data passing conventions [Contents]
The Mercury primitive types are mapped to the following C types:
Mercury type | C type |
---|---|
int | MR_Integer |
int8 | int8_t |
int16 | int16_t |
int32 | int32_t |
int64 | int64_t |
uint | MR_Unsigned |
uint8 | uint8_t |
uint16 | uint16_t |
uint32 | uint32_t |
uint64 | uint64_t |
float | MR_Float |
char | MR_Char |
string | MR_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: C# data passing conventions, Up: Data passing conventions [Contents]