[Rcpp-devel] inplace modification more affect other varibles

Chenliang Xu luckyrand at gmail.com
Wed Oct 22 20:13:29 CEST 2014


Thanks a lot!

I thought that was a bug of data.table, when I tried to learn data.table.
Obviously, I was wrong. It's a feature of data.table, in which all set
functions change their input by reference. It also provide function copy
when a copy is needed.

Based on suggestion from Romain, I may just stay on the safe side and do
not modify argument passed to C++ from R. The users of data.table should be
aware of that data.table object is passed by reference, and call function
copy when needed. For other R objects, it seems cause too much trouble.
It's hard to detect variables pointing to the same place and I don't want
to provide a copy function.

On Wed, Oct 22, 2014 at 11:40 AM, Gabor Grothendieck <
ggrothendieck at gmail.com> wrote:

> On Tue, Oct 21, 2014 at 9:22 PM, Chenliang Xu <luckyrand at gmail.com> 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.
> >
> > 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
> >
>
> This is common among C++ software called by R that modifies R objects
> in place. For example, below DT2 is modified:
>
> > library(data.table)
> ...junk...
> > DT <- data.table(a = 1:3)
> > DT2 <- DT
> > DT[, b:=a]
> > DT2
>    a b
> 1: 1 1
> 2: 2 2
> 3: 3 3
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20141022/5a59b961/attachment.html>


More information about the Rcpp-devel mailing list