Version française
Home     About     Download     Resources     Contact us    
Browse thread
Question about CAMLparamx macros
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Damien Doligez <damien.doligez@i...>
Subject: Re: [Caml-list] Question about CAMLparamx macros
On 2008-04-10, at 18:20, Raj Bandyopadhyay wrote:

> My question is, when do I have to use or not use these macros? I  
> know I need to use these when my C function accepts AND returns  
> OCaml 'value' types, but what about the following cases?

You must use the macros as soon as your function manipulates values
and can call the GC (directly or indirectly).  Since it's so hard to  
tell
whether a function can call the GC, it's safer to use them on all
functions that manipulate values.

With one very important exception: finalization functions must not
use the macros (and must never call the GC either).

> 1) When the C function takes a value as parameter or creates a value  
> local variable, but returns something else e.g.
> char *foo(value v, int x)

Use the macros.  CAMLreturnT is here exactly for this case.

> 2) When the C function does not create a value local variable  
> explicitly or takes a value as a parameter but returns the result of  
> a callback to the OCaml runtime
> e.g.
> value foo(int x) {return  
> caml_callback_exn(*caml_named_value(...),...)}

This function does manipulate *caml_named_value(...), which is a value.

BTW, the above style is extremely error-prone, because that value is  
stored
in a temporary variable that you can't pass to CAMLlocal.

Let me expand the code:

value foo (int x) {
   return caml_callback_exn (<expr1>, <expr2>);
}

Both <expr1> and <expr2> are values.  The compiled code will evaluate
them in some unspecified order.  If it evaluates one and then the other
calls the GC, you'll get a crash.  To be safe, you must make sure that
neither expression calls the GC (this is the hard way), or play it safe:

value foo (int x) {
   CAMLparam0 ();
   CAMLlocal2 (e1, e2);
   e1 = <expr1>;
   e2 = <expr2>;
   CAMLreturn (caml_callback_exn (e1, e2));
}

This way, you know there won't be a GC during the evaluation of
the arguments of caml_callback_exn.

-- Damien