[
Home
]
[ Index:
by date
|
by threads
]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
| Date: | -- (:) |
| From: | skaller <skaller@u...> |
| Subject: | Re: [Caml-list] C interface style question |
On Thu, 2006-01-19 at 09:39 +0900, Jacques Garrigue wrote: > From: Thomas Fischbacher <Thomas.Fischbacher@Physik.Uni-Muenchen.DE> > > > value-type parameters to C functions exported to OCaml should be > > registered with CAMLparamX(...). Does this hold in general, or is it > > considered acceptable/appropriate to just ignore this for "immediate" > > values that do not hold pointers, but, say, int, bool etc. values? > > Registration is required to have the GC properly update the values. > The GC may be called by any allocation. > So it is only safe not to register a parameter (or a variable) in any > of the following 4 cases. > 1) you know that it can only hold a non-pointer value (int, bool, ...) > (i.e. the GC has nothing to update) > 2) there are no allocations in your function > 3) the parameter is not accessed after the first allocation > 4) for a new variable whose contents is returned, there is no > allocation between the setting of the variable and return. > > (1) and (2) are relatively easy to see, but (3) and (4) are a bit > trickier (particularly with side-effecting expressions), so > it is not a bad idea to register more parameters than strictly > necessary. Unless I'm mistaken, 'registration' with these macros is never required: these macros are simply a high level abstraction layer providing convenience and relative safety. The Ocaml manual explains all this fairly well IMHO, the low level interface is well documented, Hendrik Tews version is cool: http://wwwtcs.inf.tu-dresden.de/~tews/htmlman-3.09/manual032.html See 18.5.2 -- IMHO the low level interface, whilst requiring more work to apply, is actually easier to understand. Just one 'BTW': I have seen some code using Field() macro with incorrect C. You must NOT do this: MyType *p = ... (MyType*)Field(v,n) = p; it isn't valid ISO C for *any* type MyType (not even 'value'). You would have to do it like this: *(MyType**)(void*)&Field(v,n) = p; // ** However I strongly recommend instead StoreField(v,n,(value)(void*)p); The incorrect usage was not detected by older versions of gcc. Gcc 4.x does detect this error. The workaround (**) is the ONLY correct way to cast an lvalue in ISO C. This problem arises in some larger codes where a macro has been used to do the type conversion .. and it appeared to work but was in fact invalid C. For example: #define MyThing(v) (MyType*)Field(v,2) is not a good idea, since MyThing(v) = ... is invalid ISO C but may not even produce a warning. You would have to instead say: #define MyThing(v) (*(MyType**)(void*)&Field(v,2)) but it seems better to rewrite your code so values and lvalues are distinguished by usage (eg 'get' and 'set' macros). [The intention of the macros is usually to abstract away the field number] -- John Skaller <skaller at users dot sf dot net> Felix, successor to C++: http://felix.sf.net