If modifying a value of an IntegerVector in Rcpp:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
void test(IntegerVector x) {
x[5] = 77;
}
After running test()
function in R :
x <- 10:1
test(x)
print(x) # 10 9 8 7 6 77 4 3 2 1
sum(x) # 55
The sum function return the value of the original array 10:1
.
How can I solve this problem?
There is no problem when using e.g. x <- sample(10L)
instead.
@F.Privé's suspicion is correct. This is an issue with ALTREP, which Rcpp does not support yet, c.f. Rcpp/#812 and Rcpp/#906. We can see this more explicitly by inspecting the variable x
:
#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
void test(IntegerVector x) {
x[5] = 77;
}
/*** R
x <- 10:1
.Internal(inspect(x))
test(x)
.Internal(inspect(x))
print(x) # 10 9 8 7 6 77 4 3 2 1
sum(x) # 55
x <- 10:1
.Internal(inspect(x))
x[6] <- 77L
.Internal(inspect(x))
print(x) # 10 9 8 7 6 77 4 3 2 1
sum(x)
*/
The first block gives:
> x <- 10:1
> .Internal(inspect(x))
@55f79a9d6c58 13 INTSXP g0c0 [NAM(3)] 10 : 1 (compact)
> test(x)
> .Internal(inspect(x))
@55f79a9d6c58 13 INTSXP g0c0 [NAM(3)] 10 : 1 (expanded)
> print(x) # 10 9 8 7 6 77 4 3 2 1
[1] 10 9 8 7 6 77 4 3 2 1
> sum(x) # 55
[1] 55
While the second block gives:
> x <- 10:1
> .Internal(inspect(x))
@55f79b1f9018 13 INTSXP g0c0 [NAM(3)] 10 : 1 (compact)
> x[6] <- 77L
> .Internal(inspect(x))
@55f7a096e5e8 13 INTSXP g0c4 [NAM(1)] (len=10, tl=0) 10,9,8,7,6,...
> print(x) # 10 9 8 7 6 77 4 3 2 1
[1] 10 9 8 7 6 77 4 3 2 1
> sum(x)
[1] 127
So after changing a value in the vector, it still claims to be 10 : 1
, for which sum
uses a short-cut. See here for further reading (including references) on ALTREP.
For now the only solution seems to be to refrain from altering the function argument.