Hi Evan, You mostly got all of this right; the topic has also been discussed a number of times before here, on SO and in other places.
On 20 March 2017 at 11:19, Evan Cortens wrote: | Hi folks, | | First, thanks for an amazing package! This is my first post to the Rcpp | listserv, so please forgive me if I'm missing something obvious. | | I've just noticed what, to me at least, is rather unexpected behaviour, as | follows: | | # Here's the Rcpp function | library(Rcpp) | | cppFunction('IntegerVector test_int_vec(IntegerVector x) { | for ( R_xlen_t i = 0; i < x.size(); i++ ) | x[i] = x[i] * 2; | return x; | }') | | # This works as expected | > a <- c(1, 2, 3, 4, 5) | > a | [1] 1 2 3 4 5 | > test_int_vec(a) | [1] 2 4 6 8 10 | > a | [1] 1 2 3 4 5 | | # But this doesn't | > b <- c(1L, 2L, 3L, 4L, 5L) | > b | [1] 1 2 3 4 5 | > test_int_vec(b) | [1] 2 4 6 8 10 | > b | [1] 2 4 6 8 10 | | | You'll see that in the first example, in which I pass a numeric vector, the | function acts as I'd expect it, namely, it returns the result of the | calculation, leaving the original vector unmodified. However, in the second | example, when I pass it an integer vector, it modifies the vector in place, and | the original vector is changed. Proxy objects. In case two an integer vector is passed as such and modified. In case one the integer vector _has to be copied first_ to a double vec, hence no in place mod. | I can only imagine this has something to do with implicit coercion: when the | reals are coerced to integers in the first example, the vector must be cloned, | whereas in the second example, in which no coercion is necessary, it's a | pointer to the original data. Another thing that leads me to believe this is | that the same thing happens in reverse if you change the return/variable type | of the function to NumericVector--reals end up being modified in place and | integers aren't. | | In my mind, one of the following things should happen: | 1) In both situations, the vector is modified in place. It does _when the object passed is of the same type as the object in the signature_. It it will happen to a numeric vector when you use Rcpp::NumericVector. | 2) In both situations, the vector is copied--probably this isn't right, as it | makes it impossible to modify in place. Also performance loss that will get worse as the date gets larger. | 3) Allow modification in place, but throw an error if the wrong type is passed. You may have to write a new compiler ... as casting from int to double is pretty standard. Dirk | | Is this a bug? Am I just misunderstanding? Any help would be appreciated! | | Thanks in advance and all best, | | Evan | | ===== | | > sessionInfo() | R version 3.3.2 (2016-10-31) | Platform: x86_64-w64-mingw32/x64 (64-bit) | Running under: Windows 7 x64 (build 7601) Service Pack 1 | | locale: | [1] LC_COLLATE=English_United States.1252 LC_CTYPE=English_United States.1252 | LC_MONETARY=English_United States.1252 LC_NUMERIC=C | | [5] LC_TIME=English_United States.1252 | | attached base packages: | [1] stats graphics grDevices utils datasets methods base | | other attached packages: | [1] Rcpp_0.12.10 | | loaded via a namespace (and not attached): | [1] tools_3.3.2 withr_1.0.2 memoise_1.0.0 digest_0.6.12 | devtools_1.12.0 | | | -- | Evan Cortens, PhD | Institutional Analyst - Office of Institutional Analysis | Mount Royal University | 403-440-6529 | _______________________________________________ | 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