From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from nez-perce.inria.fr (nez-perce.inria.fr [192.93.2.78]) by yquem.inria.fr (Postfix) with ESMTP id C1DB9BBC4 for ; Mon, 30 Jan 2006 15:05:32 +0100 (CET) Received: from pauillac.inria.fr (pauillac.inria.fr [128.93.11.35]) by nez-perce.inria.fr (8.13.0/8.13.0) with ESMTP id k0UE5WDj011163 for ; Mon, 30 Jan 2006 15:05:32 +0100 Received: from nez-perce.inria.fr (nez-perce.inria.fr [192.93.2.78]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id PAA02398 for ; Mon, 30 Jan 2006 15:05:31 +0100 (MET) Received: from mallaury.nerim.net (smtp-101-monday.noc.nerim.net [62.4.17.101]) by nez-perce.inria.fr (8.13.0/8.13.0) with ESMTP id k0UE5VeD011160 for ; Mon, 30 Jan 2006 15:05:31 +0100 Received: from karryall.dnsalias.org (oandrieu.pck.nerim.net [213.41.240.180]) by mallaury.nerim.net (Postfix) with ESMTP id CEEB74F41C; Mon, 30 Jan 2006 15:05:22 +0100 (CET) Received: by karryall.dnsalias.org (Postfix, from userid 500) id E65A4596F37; Mon, 30 Jan 2006 15:05:30 +0100 (CET) From: Olivier Andrieu MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Message-ID: <17374.7466.676326.847871@karryall.dnsalias.org> Date: Mon, 30 Jan 2006 15:05:30 +0100 To: Thomas Fischbacher Cc: caml users Subject: Re: [Caml-list] On Store_field() In-Reply-To: References: <20060119.093955.97297811.garrigue@math.nagoya-u.ac.jp> <1137640656.8943.183.camel@rosella> <02FDC6F0-122C-42BA-A2F4-15E2B08248C8@inria.fr> X-Mailer: VM 7.19 under Emacs 21.4.1 X-Miltered: at nez-perce with ID 43DE1D2C.000 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Miltered: at nez-perce with ID 43DE1D2B.000 by Joe's j-chkmail (http://j-chkmail.ensmp.fr)! X-Spam: no; 0.00; andrieu:01 oandrieu:01 nerim:01 caml-list:01 damien:01 val:01 ocaml:01 lacks:01 pointers:01 alloc:01 alloc:01 pointer:01 behaves:01 trivial:01 patching:01 X-Spam-Checker-Version: SpamAssassin 3.0.3 (2005-04-27) on yquem.inria.fr X-Spam-Level: X-Spam-Status: No, score=0.1 required=5.0 tests=FORGED_RCVD_HELO autolearn=disabled version=3.0.3 Thomas Fischbacher [Monday 30 January 2006] : > > > On Thu, 19 Jan 2006, Damien Doligez wrote: > > > >However I strongly recommend instead > > > > > > StoreField(v,n,(value)(void*)p); > > > > This is the only way. Always use Store_field, Store_double_field, > > and Store_double_val. > > What you *actually* forgot to tell people is that OCaml > unfortunately lacks a macro with which one can store C pointers to > alloc_final allocated blocks. If one writes to those using e.g. > > ml_vector = alloc_final(2, finalize_vector, 1, 10); > Store_field(ml_vector, 1,(value)vector); > > with vector being a C pointer to a structure, this may or may not > lead to random crashes at very unexpected places - because (as I > think now) the Store_field macro will be over-eager trying to tell > the GC about the value stored - which it should just ignore in this > particular case! > > Indeed, this has been discussed before, I think: > > http://groups.google.de/group/fa.caml/msg/60ace9405fcf60c0?dmode=source&hl=de > > So, I would strongly suggest introducing a macro that behaves like this: > > #define Store_c_field(block,offset,x) (Field(block,offset)=(value)x) > > so that one could then use > > Store_c_field(ml_vector, 1,vector); > > I actually just spent a full week tracking down precisely this > issue in a not particularly trivial C library interface I am > building right now. After looking in the weirdest places, ensuring > it's not an issue with the library wrapped, or the trickier pieces > of my own code, I even started patching debugging code into the > OCaml bytecode's GC and rebuilding... > > So, *please* do the world a great favour and tell people about that > issue in the C interface documentation! Well, it already does: ,---- | Rule 3 Assignments to the fields of structured blocks must be done | with the Store_field macro (for normal blocks) or Store_double_field | macro (for arrays and records of floating-point numbers). Other | assignments must not use Store_field nor Store_double_field. `---- Final (aka custom) blocks are not structured blocks but raw blocks (not traced by the GC), so assignements to those blocks falls in the "other assignments" category. A good way to deal with custom blocks in the C code is to create a small struct type and access the content of the block through this type. struct custom_foo_bar { foo *pointer1; bar *pointer3; }; value alloc_foo_bar (foo *f, bar *b) { value v; struct custom_foo_bar *s; v = alloc_custom (&foo_bar_ops, sizeof struct custom_foo_bar, 1, 10); s = Data_custom_val (v); s->p1 = f; s->p2 = b; return v; } -- Olivier