Next: , Previous: , Up: Interfacing with C   [Contents]


14.10.1.4 Using pragma foreign_proc for 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.


Next: , Previous: , Up: Interfacing with C   [Contents]