[Rcpp-devel] inplace modification more affect other varibles

Gabor Grothendieck ggrothendieck at gmail.com
Wed Oct 22 18:40:05 CEST 2014


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


More information about the Rcpp-devel mailing list