Next: Using pragma foreign_export for C, Previous: Using pragma foreign_enum for C, Up: Interfacing with C
The input and output variables will have C types corresponding to their Mercury types, as determined by the rules specified in C data passing conventions.
The C code fragment may declare local variables, up to a total size of 10kB for the procedure. If a procedure requires more than this for its local variables, the code can be moved into a separate function (defined in a ‘pragma foreign_code’ declaration, for example).
The C code fragment should not declare any labels or static variables unless there is also a ‘pragma no_inline’ declaration or a ‘may_not_duplicate’ foreign code attribute for the procedure. The reason for this is that otherwise the Mercury implementation may inline the procedure by duplicating the C code fragment for each call. If the C code fragment declared a static variable, inlining it in this way could result in the program having multiple instances of the static variable, rather than a single shared instance. If the C code fragment declared a label, inlining it in this way could result in an error due to the same label being defined twice inside a single C function.
C code in a pragma foreign_proc declaration for any procedure whose
determinism indicates that it can fail must assign a truth value to the macro
‘SUCCESS_INDICATOR’.
For example:
:- pred string.contains_char(string, character).
:- mode string.contains_char(in, in) is semidet.
:- pragma foreign_proc("C",
string.contains_char(Str::in, Ch::in),
[will_not_call_mercury, promise_pure],
"SUCCESS_INDICATOR = (strchr(Str, Ch) != NULL);").
SUCCESS_INDICATOR should not be used other than as the target of
an assignment.
(For example, it may be #defined to a register, so you should not
try to take its address.)
Procedures whose determinism indicates that they cannot fail
should not access SUCCESS_INDICATOR.
Arguments whose mode is input will have their values set by the Mercury
implementation on entry to the C code.
If the procedure succeeds, the C code must set the values of all output
arguments.
If the procedure fails, the C code need only set SUCCESS_INDICATOR to
false (zero).
The behaviour of a procedure defined using a ‘pragma foreign_proc’ declaration whose body contains a ‘return’ statement is undefined.