From P.Dalgaard at biostat.ku.dk  Wed Jan 16 10:58:31 2008
From: P.Dalgaard at biostat.ku.dk (Peter Dalgaard)
Date: Wed, 16 Jan 2008 10:58:31 +0100
Subject: [Rd] Pb with defineVar() example in the "Writing R Extensions"
 manual
In-Reply-To: <478D549E.40406@fhcrc.org>
References: <478D549E.40406@fhcrc.org>
Message-ID: <478DD547.5080608@biostat.ku.dk>

Herve Pages wrote:
> Hi,
>
> I'm wondering if this code from the "Writing R Extensions" manual
> is really safe:
>
>      SEXP mkans(double x)
>      {
>          SEXP ans;
>          PROTECT(ans = allocVector(REALSXP, 1));
>          REAL(ans)[0] = x;
>          UNPROTECT(1);
>          return ans;
>      }
>
>      double feval(double x, SEXP f, SEXP rho)
>      {
>          defineVar(install("x"), mkans(x), rho);
>          return(REAL(eval(f, rho))[0]);
>      }
>
> In C, the order in which function arguments are evaluated before the
> function itself is called is undefined. Hence there is no guarantee
> that install("x") will be evaluated before mkans(x). What happens if
> mkans(x) is evaluated first? Then install("x") will be called and
> eventually trigger garbage collection while the SEXP returned by
> mkans(x) is still unprotected.
>
> I'm asking because I'm getting all sorts of problems with
>
>   defineVar(install(somekey), mkans(x), rho);
>
> In my code this line is inside a big loop (hundred of thousands of
> iterations) so I end up with a lot of symbols in the rho environment.
>
> The problems I've seen are hard to reproduce: sometimes it's a segfault,
> sometimes a "cons memory exhausted" error, or sometimes everything looks
> fine except that, later, when I retrieve values from the rho environment
> with findVar(), some of them are altered!
>
> But if I replace the above line by:
>
>   PROTECT(ans = mkans(x));
>   defineVar(install(somekey), ans, rho);
>   UNPROTECT(1);
>
> then everything works fine :-)
>
>   
Sounds like you are right. You don't really have the "smoking gun", but
it doesn't seem to be worth trying to catch the actual bug in action
with hardware watchpoints and whatnot.

The opposite fix should work too (does it?):

{ SEXP sym = install(somekey) ; defineVar(sym, mkans(x), rho);}

(I don't think you need to  PROTECT elements in the symbol table)

-- 
   O__  ---- Peter Dalgaard             ?ster Farimagsgade 5, Entr.B
  c/ /'_ --- Dept. of Biostatistics     PO Box 2099, 1014 Cph. K
 (*) \(*) -- University of Copenhagen   Denmark          Ph:  (+45) 35327918
~~~~~~~~~~ - (p.dalgaard at biostat.ku.dk)                  FAX: (+45) 35327907



[Rd] Pb with defineVar() example in the "Writing R Extensions" manual
Peter Dalgaard