[Rcpp-devel] Unintentional modification of vector in place?

Evan Cortens ecortens at mtroyal.ca
Mon Mar 20 19:02:54 CET 2017


Hi Dirk,

Thanks very much! Apologies for posting about something that has been
covered elsewhere, I did search, but clearly not well enough. (Indeed, I
see, this is almost exactly the same issue:
https://stackoverflow.com/questions/11300048/rcpp-pass-by-reference-vs-by-value
)

On (3), apologies for being unclear, of course casting from int to double
isn't an issue. I meant to say it could be an issue the other way around,
namely, double to int. If you instead pass, for example, c(1.1, 2.2, 3.3,
4.4, 5.5, 6.6) to my example function, it'll silently cast that to an
integer vector c(1, 2, 3, 4, 5, 6) (i.e., truncating). That said, this
isn't really unexpected behaviour, rather exactly what you'd expect if you
did {double x = 1.1; int y = (int) x;} in C. I'll pass on writing my own
compiler, at least for now :)

Finally, just to close the loop on this and to make sure I understand... if
I don't want to modify the original vector, I should do this, yes?

cppFunction('IntegerVector test_int_vec(IntegerVector x) {
  IntegerVector y = clone(x);
  for ( R_xlen_t i = 0; i < x.size(); i++ )
    y[i] = y[i] * 2;
  return y;
}')

Thanks again!

Evan

On Mon, Mar 20, 2017 at 11:44 AM, Dirk Eddelbuettel <edd at debian.org> wrote:

>
> 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 at lists.r-forge.r-project.org
> | https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel
>
> --
> http://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org
>



-- 
Evan Cortens, PhD
Institutional Analyst - Office of Institutional Analysis
Mount Royal University
403-440-6529
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.r-forge.r-project.org/pipermail/rcpp-devel/attachments/20170320/754b9b40/attachment-0001.html>


More information about the Rcpp-devel mailing list