[Rcpp-devel] ivec and imat don't pass by reference

Dirk Eddelbuettel edd at debian.org
Tue Sep 15 13:53:32 CEST 2015


On 15 September 2015 at 12:16, Serguei Sokol wrote:
| Hi,
| 
| If we declare the following toy function where a numeric matrix is passed by reference,
| it works as expected, the matrix m is modified "in place":
| 
| cppFunction('
| mat m2(mat& m) {
|     m=m*2;
|     return(m);
| }', depends="RcppArmadillo", inc="using namespace arma;")
| m=matrix(1:4, 2)+pi
| m2(m)
|            [,1]     [,2]
| [1,]  8.283185 12.28319
| [2,] 10.283185 14.28319
| m
|            [,1]     [,2]
| [1,]  8.283185 12.28319
| [2,] 10.283185 14.28319
| 
| But if we pass to imat type, the call by reference is no more functionning:
| cppFunction('
| imat im2(imat& m) {
|     m=m*2;
|     return(m);
| }', depends="RcppArmadillo", inc="using namespace arma;")
| im=matrix(1:4, 2)
| im2(im)
|       [,1] [,2]
| [1,]    2    6
| [2,]    4    8
| im
|       [,1] [,2]
| [1,]    1    3
| [2,]    2    4
| 
| The original matrix im remains as it was.
| You can easyly verify that the same is true for ivec type.
| Is it intended behaviour?

It is something else, which is a slight trick:  your 'm' is not an integer
matrix, so you are forcing a copy, which breaks the reference semantics.

See here using your code:

R> library(Rcpp)
R> cppFunction('imat im2(imat& m) { m=m*2; return(m); }', depends="RcppArmadillo", inc="using namespace arma;")
R> m <- matrix(c(1L,2L,3L,4L), 2)
R> m
     [,1] [,2]
[1,]    1    3
[2,]    2    4
R> storage.mode(m)
[1] "integer"
R> im2(m)
     [,1] [,2]
[1,]    2    6
[2,]    4    8
R> m
     [,1] [,2]
[1,]    2    6
[2,]    4    8
R> 

So if we pass an integer matrix down, it gets changed as a side effect.  

Dirk

-- 
http://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org


More information about the Rcpp-devel mailing list