From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail1-relais-roc.national.inria.fr (mail1-relais-roc.national.inria.fr [192.134.164.82]) by walapai.inria.fr (8.13.6/8.13.6) with ESMTP id p7G9L9SK010108 for ; Tue, 16 Aug 2011 11:21:09 +0200 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: At8CAKs1Sk7RVdg2kGdsb2JhbABBqCIIFAEBAQEJCQ0HFAQhgUABAQEBAgESAiwBGx4DAQsGBQsNLiIBEQEFARwGEyKHTpwuCow3glWFODuIbQIDBoZBBIdZizmMWTyDZQ X-IronPort-AV: E=Sophos;i="4.67,379,1309730400"; d="scan'208";a="115965012" Received: from mail-qw0-f54.google.com ([209.85.216.54]) by mail1-smtp-roc.national.inria.fr with ESMTP/TLS/RC4-SHA; 16 Aug 2011 11:21:03 +0200 Received: by qwc9 with SMTP id 9so5040845qwc.27 for ; Tue, 16 Aug 2011 02:21:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :content-type:content-transfer-encoding; bh=J7/AEaxOIustEMoIGIxJK5Ut11hoIN/iDLnSayvaXcI=; b=Ymol/X90exfRX7rvHR5xA82wVPd7d1X0jb0s0wXJOMEguzYkNIzA56l4BDqg6p6CNo 8tPHYnLdV30WLdfcsfJkWDMzs8LWqEGisGEyQdtz9beWSgvMHbeV0LFBiW2zNbpdScvj dEw6pzyIb1x3yb2vCtQf6ODCQyXyR+g8tHatA= MIME-Version: 1.0 Received: by 10.229.19.193 with SMTP id c1mr3230756qcb.118.1313486463057; Tue, 16 Aug 2011 02:21:03 -0700 (PDT) Received: by 10.229.76.229 with HTTP; Tue, 16 Aug 2011 02:21:02 -0700 (PDT) In-Reply-To: <20110816.105738.246515733851238101.Christophe.Troestler@umons.ac.be> References: <20110816.105738.246515733851238101.Christophe.Troestler@umons.ac.be> Date: Tue, 16 Aug 2011 13:21:02 +0400 Message-ID: From: Dmitry Bely To: Caml List Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 8bit X-MIME-Autoconverted: from quoted-printable to 8bit by walapai.inria.fr id p7G9L9SK010108 Subject: Re: [Caml-list] Interfacing with C: bad practice On Tue, Aug 16, 2011 at 12:57 PM, Christophe TROESTLER wrote: > On Tue, 16 Aug 2011 11:37:03 +0400, Dmitry Bely wrote: >> >> 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. > > Are you sure it is not because, in this way, “list” is being > registered twice? Where? >  IMHO, wrp_ml_cons does not need to register values. Let me explain again. Before wrp_ml_cons() is called, C compiler 1. Pushes a _copy_ of list value onto the stack. 2. Calls caml_copy_string(*s) and pushes its result onto the stack also. 3. Calls wrp_ml_cons(). After (2) the second parameter of wrp_ml_cons() becomes invalid: it is a _copy_ of list, not registered as a local root. Already two persons don't see the problem at first glance; It proves that I was right starting the topic ;-) - Dmitry Bely