[Rcpp-devel] Extract a function from a list and create a call

Douglas Bates bates at stat.wisc.edu
Mon Mar 22 23:29:42 CET 2010


On Mon, Mar 22, 2010 at 10:21 AM, Romain Francois
<romain.francois at dbmail.com> wrote:
> Le 22/03/10 14:14, Douglas Bates a écrit :
>>
>> I think the problem under Linux is extracting fam[0].  The error
>> message to me indicates that even though fam is declared as a
>> CharacterVector the SEXP it contains isn't a STRSXP.
>
> This is not supposed to happen. The constructor of CharacterVector makes
> sure the SEXP is a STRSXP.
>
> Vector( SEXP x ) : Base() {
>    Base::setSEXP( r_cast<RTYPE>( x ) ) ;
> }
>
> and r_cast attempts to convert x to a STRSXP and throws otherwise.
>
>
>
>
> When we do :
>
> List ll(l) ;
> CharacterVector fam = ll["family"] ;
>
> ll["family"] makes a generic_name_proxy, we then ask to convert it to a
> CharacterVector, so the templated conversion operator is called :
>
> template <typename T>
> operator T(){
>        return ::Rcpp::as<T>( get() ) ;
> }
>
> with T = CharacterVector, so then as<CharacterVector> is called, which
> eventually calls CharacterVector( SEXP) constructor, so fam should refer to
> a STRSXP.
>
>
>
>
> You can do things like this to debug further.
>
> Function str("str") ;
> Rf_PrintValue( str( fam ) ) ;
>
> to check.
>
> or maybe even use the internal inspect:
>
> inspect <- function(...) .Internal(inspect(...))
>
>
> Function inspect("inspect") ;
> Rf_PrintValue( inspect( fam ) ) ;

Thanks for the suggestions.  I should have realized that I can call
str and inspect from within a C++ program compiled against Rcpp but I
am still getting used to the flexibility that Rcpp offers.

My test function is now

inspect <- function(...) .Internal(inspect(...))
fx <- cfunction( signature( l = "list" ), '
   Function str("str"), inspect("inspect");
   List ll(l);
   CharacterVector fam = ll["family"];
   Rprintf("Assigned fam of length %d\\n", fam.size());
   Rf_PrintValue(str(fam));
   Rf_PrintValue(inspect(fam));
   char *fpt = (char *)0;
   Rprintf("Initialized char * pointer to zero\\n");
   if (fam.size()) fpt = fam[0];
   Rprintf("Assigned fpt\\n");
   return R_NilValue;
//List::create(_["fam"] = std::string(fpt));
', Rcpp = TRUE, includes = "using namespace Rcpp;" )

and this segfaults on an Ubuntu (karmic) amd64 running a locally
compiled R-devel.

> sessionInfo()
R version 2.11.0 Under development (unstable) (2010-03-18 r51313)
x86_64-unknown-linux-gnu

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C
 [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8
 [5] LC_MONETARY=C              LC_MESSAGES=en_US.UTF-8
 [7] LC_PAPER=en_US.UTF-8       LC_NAME=C
 [9] LC_ADDRESS=C               LC_TELEPHONE=C
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base

other attached packages:
[1] Rcpp_0.7.10.3 inline_0.3.4
> fx(binomial())
Assigned fam of length 1
 chr "binomial"
NULL
@2acb128 16 STRSXP g0c1 [NAM(2)] (len=1, tl=0)
  @2d39830 09 CHARSXP g0c2 [MARK,gp=0x21,ATT] "binomial"
[1] "binomial"
Initialized char * pointer to zero

 *** caught segfault ***
address (nil), cause 'memory not mapped'

Traceback:
 1: .Call("file327b23c6", PACKAGE = f, l)
 2: fx(binomial())

It looks as if the segfault is occurring when extracting a char *
pointer for fam[0].  I don't know if the problem is in the fam[0]
operation or the extracting a char *.


More information about the Rcpp-devel mailing list