[Rd] "Writing R Extensions": bad example with CAR / CDR as lvalues (PR#11054)

sanders at fs.tum.de sanders at fs.tum.de
Sun Mar 30 00:40:09 CET 2008


Full_Name: Simon Anders
Version: 2.6.2
OS: Ubuntu Linux 
Submission from: (NULL) (86.22.75.91)


This is a rather minor "documentation bug", certainly not at all urgent.

The manual "Writing R extensions" explains in section 5.10 ("Evaluating R
expressions from C") how to use the eval function. Without going into much
details, an example is given how to build up a LANGSXP pairlist to represent an
expression.

This example is taken at verbatim from src/main/print.c, and uses CAR and CDR as
l-values, e.g.
   CAR(t) = install("print")

This has just confused me quite a bit, as my own code, which I wrote following
this example, did not compile, complaining about 'CAR(t)' being illegal as
l-value.

After a while I figured out the reason, which is (as you probably have spotted
immediatly) that the example is taken from a code snipped that imports
Rinternals.h with defined USE_RINTERNALS, while I followed the manual's advice
to not define USE_RINTERNALS for extensions.

Maybe you could add a note in this section of the manual that one should use
SETCAR and SETCDR instead. A more illustrative example would be even better.


Just in case you want to use it as example, here is my code. I hope it is
correct in your expert eyes.

   /* Remove the variable with name s from the environment ev, 
      i.e. construct the call: rm( list=s, envir=ev ) */

   SEXP call;
   PROTECT( call = Rf_allocList( 3 ) );
   SET_TYPEOF( call, LANGSXP );
   
   SETCAR( call, install( "rm" ) );
   
   SETCAR( CDR(call), allocVector( STRSXP, 1 ) );
   SET_STRING_ELT( CAR( CDR(call) ), 0, mkChar( s ) );
   SET_TAG( CDR(call), install("list") );
   
   SETCAR( CDDR(call), ev );
   SET_TAG( CDDR(call), install("envir") );

   eval( call, R_GlobalEnv );
   UNPROTECT( 1 );



More information about the R-devel mailing list