[Rcpp-devel] Some questions regarding internals of Rcpp objects

Dirk Eddelbuettel edd at debian.org
Fri Aug 5 18:50:03 CEST 2011


Hi Ulrich,

These are really several questions.  I'll try to address them all, with some
luck maybe Romain, Doug, Christian, ... will correct or complement as needed.

On 5 August 2011 at 11:45, Ulrich Bodenhofer wrote:
| Dear list members,
| 
| I have started developing a package using the latest version of Rcpp just
| recently, so I am more or less an Rcpp newbie. Since I am not sufficiently
| proficient in advanced C++ (and admittedly too lazy too) to analyze the Rcpp
| source code, I have some questions regarding what actually happens inside Rcpp.
| Let me bother you with an example:
| 
| RcppExport SEXP test(SEXP mat)
| {
| BEGIN_RCPP
|     Rcpp::NumericMatrix matC(mat);
|     Rcpp::NumericMatrix matD(mat);
| 
|     matC(1, 1) = 1;
|     matD(1, 1) = -matD(1, 1);
| 
|     return(matC);
| END_RCPP
| }
| 
| If I call this function on some matrix, then the function returns the input
| matrix with its element [2, 2] set to 1, but that's all. The change in matD
| only seems to have an effect on the local copy matD. If I replace "return(matC)
| " by "return(matD)", then the function returns the input matrix with the sign
| of its element [2, 2] inverted, so the change in matC has no effect. That Rcpp
| creates local copies, i.e. that matC and matD are independent objects each
| holding local copies of the argument mat, would perfectly explain these

This has been discussed here before.  The matrices both receive a _pointer_
(as a SEXP is a pointer) to the original memory of the R-level matrix you
pass in.  

You need to explicitly request deep copies via clone() if you want that.  See
this variant:

R> fun <- cxxfunction(signature(mat="numeric"), plugin="Rcpp", body='
+      Rcpp::NumericMatrix matC(mat);
+      Rcpp::NumericMatrix matD(mat);
+ 
+      matC(1, 1) = 1;
+      matD(1, 1) = -matD(1, 1);
+ 
+      return(Rcpp::List::create(Rcpp::Named("C")=matC,
+                                Rcpp::Named("D")=matD));
+ ');
R> fun(matrix(42,2,2))
$C
     [,1] [,2]
[1,]   42   42
[2,]   42   -1

$D
     [,1] [,2]
[1,]   42   42
[2,]   42   -1

R> 

So C and D are really the same thing.


| results. Previously, however, I thought Rcpp would only wrap an R/SEXP object
| into an Rcpp object without making a copy. If it was so, no matter whether the
| function returns matC or matD, the function would return the input matrix with
| -1 on position [2, 2]. Did I get this point wrong? I suppose it would save time
| and memory not to create a copy, in particular, since arguments to functions
| are local copies already. Is there a way to avoid copying?
| 
| A related question is what the "=" operator does. Does
| 
|     Rcpp::NumericVector x = ...;
| 
| create a copy or is it only a pointer that is assigned?

IIRC the pointer is copied, yet still points to same memory address.
 
| My final question concerns the "longevity" of Rcpp objects. Suppose I do the
| following:
| 
|     {
|         Rcpp::NumericVector vec(10);
|         double *p = vec.begin();
|     }
| 
| Can I use *p outside this block or is the pointer killed along with the
| variable vec after the block is closed? According to my limited knowledge, I

p as a variable is gone outside of this { } scope. So is vec but as you say ...

| would assume that it is only the reference vec that is not available outside
| the block, but that the corresponding R object still exists and will be deleted
| by the R garbage collector only after the whole function has terminated.

... we do not explicitly destroy in the destructor but let R take care of
it. So it will live "some random amount" of time you have no control over. Eeek.

In a nutshell, if you want longer-living objects, assign in R before you call
a function -- you are pretty much guaranteed it will be there.

If you need persistence between different calls from R you need an object
that persists, and there are many possible C++ tricks to do that.
 
| Any help is gratefully appreciated! I am sorry if these are stupid questions or
| if any of them have been discussed previously.

Great questions, but some of the material has been discussed before.  We
probably need a better FAQ or better search engine...

Cheers, Dirk
| 
| Thanks and best regards,
| Ulrich
| 
| 
| ----------------------------------------------------------------------
| _______________________________________________
| Rcpp-devel mailing list
| Rcpp-devel at lists.r-forge.r-project.org
| https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel

-- 
Gauss once played himself in a zero-sum game and won $50.
                      -- #11 at http://www.gaussfacts.com


More information about the Rcpp-devel mailing list