Thanks a lot! Does that mean we should never modify an argument passed from R to cpp?
On Wed, Oct 22, 2014 at 8:24 AM, Romain Francois <rom...@r-enthusiasts.com> wrote: > a and b are the same object: > > > a <- seq(1, 0.1, -0.1) > > b <- a > > pryr::address( a ) > [1] "0x7f9504534948" > > pryr::address( b ) > [1] "0x7f9504534948" > > So clone is what you need here. > > Implementing copy on write for that kind of example is possible, but would > require a lot of additional code, i.e. the iterator would need to handle > the write operation. > > An undesirable side effect of this is that such iterators would be quite > less performant, right now Rcpp is close to the metal and uses direct > pointers as iterators when it makes sense. A price that everyone would have > to pay. no go. > > Instead, the responsibility is given to the user to clone explicitly when > changes will be made to the underlying object. > > Romain > > > Le 22 oct. 2014 à 04:13, Chenliang Xu <luckyr...@gmail.com> a écrit : > > 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 > > >
_______________________________________________ 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