I would like to share my experience of writing bad C bindings. The following code is wrong, although no "living in harmony with the garbage collector" rule seems to be violated:
value wrp_ml_cons (value v, value l) { CAMLparam2(v, l); CAMLlocal1(cell); cell = caml_alloc_small(2, Tag_cons); Field(cell, 0) = v; Field(cell, 1) = l; CAMLreturn(cell); } value string_list(const char ** s) { CAMLparam0(); CAMLlocal1(list); list = Val_emptylist; while (*s != NULL) { list = wrp_ml_cons(caml_copy_string(*s), list); /* bug! */ } CAMLreturn(list); } In the line list = wrp_ml_cons(caml_copy_string(*s), list); /* bug! */ C compiler first puts "list" pointer on stack and then calls caml_copy_string(*s), potentially invalidating "list". Of course, the stack copy of "list" is not registered as a global root so wrp_ml_cons gets an invalid value. Maybe Ocaml docs should be updated to warn about pitfalls like that? - Dmitry Bely -- Caml-list mailing list. Subscription management and archives: https://sympa-roc.inria.fr/wws/info/caml-list Beginner's list: http://groups.yahoo.com/group/ocaml_beginners Bug reports: http://caml.inria.fr/bin/caml-bugs