Hi Dirk, Thanks for your quick answer. I don't think Rcpp::clone is what I was looking for. I know `stl_sort_inplace(a)` modify the value of `a`, but it surprise me to see it modify `b`. And it may modify some other variables c, d, e, f..., and it's hard to know which variables point to the same place.
On Tue, Oct 21, 2014 at 8:31 PM, Dirk Eddelbuettel <e...@debian.org> wrote: > > On 21 October 2014 at 20:22, Chenliang Xu wrote: > | Hello, > | > | With the following inplace sorting example, I understand the value of > `a` is > | sorted inplace, but it's strange to see the value of `b` is also > modified. This > | can cause some hard to detect bug, since the cpp function may modify a > variable > | defined in other scope. > > Very well known issue -- maybe do a search for 'Rcpp::clone' ... > > In a nutshell, SEXP objects are passed by a __pointer__ and changes do > therefore persist. If you want distinct copies, use Rcpp::clone(). > > Dirk > > | It seems that rcpp doesn't respect the named field, which is adopted by > R to > | implement copy-on-modify. I don's see an easy fix on C++ side, since the > called > | cpp function has no information about variable binding in R. A possible > fix is > | adding a function `inplace` to R, which ensure the returned variable has > named > | filed = 0 so is safe to modify inplace. Then, we have to call the > function as > | `stl_sort_inplace(inplace(a))`, which seems odd but is also informative. > It > | shows clearly that we are breaking the pass-by-value rule in R. > | > | ```cpp > | #include <Rcpp.h> > | using namespace Rcpp; > | > | // [[Rcpp::export]] > | void stl_sort_inplace(NumericVector x) { > | std::sort(x.begin(), x.end()); > | } > | > | ``` > | > | ```r > | a <- seq(1, 0.1, -0.1) > | b <- a > | # [1] 1.0 0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2 0.1 > | > | stl_sort_inplace(a) > | > | a > | # [1] 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 > | > | b > | # [1] 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 > | > | a <- seq(1, 0.1, -0.1) > | pure_function <- function (x) { > | y <- x > | stl_sort_inplace(y) > | print(y) > | } > | pure_function(a) > | a > | # [1] 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0 > | > | ``` > | > | _______________________________________________ > | Rcpp-devel mailing list > | Rcpp-devel@lists.r-forge.r-project.org > | https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel > > -- > http://dirk.eddelbuettel.com | @eddelbuettel | e...@debian.org >
_______________________________________________ Rcpp-devel mailing list Rcpp-devel@lists.r-forge.r-project.org https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel