|
R-devel,
I have noticed that making a copy of an object in R prior to using .Call on the original object can cause the C code to alter not only the object passed to it but also the copy in R. A simple example is: > x <- 2 > y <- x > .Call("addOne", x, DUP=TRUE) # Changing DUP does not alter output NULL > x [1] 3 > y [1] 3 And corresponding simple C code: "test.c": #include <R.h> #include <Rinternals.h> #include <Rmath.h> SEXP addOne(SEXP input) { REAL(input)[0] = REAL(input)[0] + 1; return R_NilValue; } I assume that this is simply a result of lazy loading in R, and well documented. My question is, do there exist functions to (1) force R to make a copy of an object (force() does not work), and (2) to check whether two objects are actually pointing to the same memory address. For question 1, I have found specific operations which force a copy of a given datatype, but would prefer a more general solution. Thank you, Taylor > sessionInfo() R version 2.14.1 (2011-12-22) Platform: x86_64-apple-darwin9.8.0/x86_64 (64-bit) locale: [1] en_GB.UTF-8/en_GB.UTF-8/en_GB.UTF-8/C/en_GB.UTF-8/en_GB.UTF-8 attached base packages: [1] stats graphics grDevices utils datasets methods base loaded via a namespace (and not attached): [1] tools_2.14.1 -- Taylor B. Arnold Department of Statistics Yale University 24 Hillhouse Avenue New Haven, CT 06520 e-mail: [hidden email] ______________________________________________ [hidden email] mailing list https://stat.ethz.ch/mailman/listinfo/r-devel |
|
On Jan 11, 2012, at 12:08 PM, Taylor Arnold wrote: > R-devel, > > I have noticed that making a copy of an object in R prior to using > .Call on the original object can > cause the C code to alter not only the object passed to it but also > the copy in R. Please see the docs - .Call does *NOT* have a DUP argument - you are responsible for duplication at all times if you make modifications (e.g. using duplicate()). Cheers, Simon > A simple example > is: > >> x <- 2 >> y <- x >> .Call("addOne", x, DUP=TRUE) # Changing DUP does not alter output > NULL >> x > [1] 3 >> y > [1] 3 > > And corresponding simple C code: > > "test.c": > #include <R.h> > #include <Rinternals.h> > #include <Rmath.h> > > SEXP addOne(SEXP input) { > REAL(input)[0] = REAL(input)[0] + 1; > return R_NilValue; > } > > I assume that this is simply a result of lazy loading in R, and well > documented. My question is, do > there exist functions to (1) force R to make a copy of an object > (force() does not work), and (2) to check > whether two objects are actually pointing to the same memory address. > For question 1, I have > found specific operations which force a copy of a given datatype, but > would prefer a more general > solution. > > Thank you, > > Taylor > >> sessionInfo() > R version 2.14.1 (2011-12-22) > Platform: x86_64-apple-darwin9.8.0/x86_64 (64-bit) > > locale: > [1] en_GB.UTF-8/en_GB.UTF-8/en_GB.UTF-8/C/en_GB.UTF-8/en_GB.UTF-8 > > attached base packages: > [1] stats graphics grDevices utils datasets methods base > > loaded via a namespace (and not attached): > [1] tools_2.14.1 > > > -- > Taylor B. Arnold > Department of Statistics > Yale University > 24 Hillhouse Avenue > New Haven, CT 06520 > > e-mail: [hidden email] > > ______________________________________________ > [hidden email] mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel > > ______________________________________________ [hidden email] mailing list https://stat.ethz.ch/mailman/listinfo/r-devel |
|
On Wed, Jan 11, 2012 at 11:49 AM, Simon Urbanek
<[hidden email]> wrote: > > On Jan 11, 2012, at 12:08 PM, Taylor Arnold wrote: > >> R-devel, >> >> I have noticed that making a copy of an object in R prior to using >> .Call on the original object can >> cause the C code to alter not only the object passed to it but also >> the copy in R. > Please see the docs - .Call does *NOT* have a DUP argument - you are responsible for duplication at all times if you make modifications (e.g. using duplicate()). Except that duplicate will create a new SEXPREC and the original poster wanted to modify the SEXPREC passed through a pointer in .Call. Purposely changing the value of arguments to .Call is a bad design, Taylor. R is a functional language and this breaks the functional semantics. It is the sort of thing that you do only when you can't think of a better approach. It may, perhaps, be justified if the R objects you are passing happen to be fields in a reference class (see ?setRefClass) but otherwise it is just opening yourself up to errors. At the level of C/C++ all R objects passed as arguments to .Call should be regarded as const SEXP >> A simple example >> is: >> >>> x <- 2 >>> y <- x >>> .Call("addOne", x, DUP=TRUE) # Changing DUP does not alter output >> NULL >>> x >> [1] 3 >>> y >> [1] 3 >> >> And corresponding simple C code: >> >> "test.c": >> #include <R.h> >> #include <Rinternals.h> >> #include <Rmath.h> >> >> SEXP addOne(SEXP input) { >> REAL(input)[0] = REAL(input)[0] + 1; >> return R_NilValue; >> } >> >> I assume that this is simply a result of lazy loading in R, and well >> documented. My question is, do >> there exist functions to (1) force R to make a copy of an object >> (force() does not work), and (2) to check >> whether two objects are actually pointing to the same memory address. >> For question 1, I have >> found specific operations which force a copy of a given datatype, but >> would prefer a more general >> solution. >> >> Thank you, >> >> Taylor >> >>> sessionInfo() >> R version 2.14.1 (2011-12-22) >> Platform: x86_64-apple-darwin9.8.0/x86_64 (64-bit) >> >> locale: >> [1] en_GB.UTF-8/en_GB.UTF-8/en_GB.UTF-8/C/en_GB.UTF-8/en_GB.UTF-8 >> >> attached base packages: >> [1] stats graphics grDevices utils datasets methods base >> >> loaded via a namespace (and not attached): >> [1] tools_2.14.1 >> >> >> -- >> Taylor B. Arnold >> Department of Statistics >> Yale University >> 24 Hillhouse Avenue >> New Haven, CT 06520 >> >> e-mail: [hidden email] >> >> ______________________________________________ >> [hidden email] mailing list >> https://stat.ethz.ch/mailman/listinfo/r-devel >> >> > > ______________________________________________ > [hidden email] mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel ______________________________________________ [hidden email] mailing list https://stat.ethz.ch/mailman/listinfo/r-devel |
|
In reply to this post by Simon Urbanek
On 11.01.2012 18:49, Simon Urbanek wrote: > > On Jan 11, 2012, at 12:08 PM, Taylor Arnold wrote: > >> R-devel, >> >> I have noticed that making a copy of an object in R prior to using >> .Call on the original object can >> cause the C code to alter not only the object passed to it but also >> the copy in R. > > Please see the docs - .Call does *NOT* have a DUP argument - you are responsible for duplication at all times if you make modifications (e.g. using duplicate()). > > Cheers, > Simon > > >> A simple example >> is: >> >>> x<- 2 >>> y<- x >>> .Call("addOne", x, DUP=TRUE) # Changing DUP does not alter output >> NULL >>> x >> [1] 3 >>> y >> [1] 3 >> >> And corresponding simple C code: >> >> "test.c": >> #include<R.h> >> #include<Rinternals.h> >> #include<Rmath.h> >> >> SEXP addOne(SEXP input) { >> REAL(input)[0] = REAL(input)[0] + 1; >> return R_NilValue; >> } >> >> I assume that this is simply a result of lazy loading In addition to Simon: it is "lazy evalution" rather than lazy loading in this case. Uwe >> in R, and well >> documented. My question is, do >> there exist functions to (1) force R to make a copy of an object >> (force() does not work), and (2) to check >> whether two objects are actually pointing to the same memory address. >> For question 1, I have >> found specific operations which force a copy of a given datatype, but >> would prefer a more general >> solution. >> >> Thank you, >> >> Taylor >> >>> sessionInfo() >> R version 2.14.1 (2011-12-22) >> Platform: x86_64-apple-darwin9.8.0/x86_64 (64-bit) >> >> locale: >> [1] en_GB.UTF-8/en_GB.UTF-8/en_GB.UTF-8/C/en_GB.UTF-8/en_GB.UTF-8 >> >> attached base packages: >> [1] stats graphics grDevices utils datasets methods base >> >> loaded via a namespace (and not attached): >> [1] tools_2.14.1 >> >> >> -- >> Taylor B. Arnold >> Department of Statistics >> Yale University >> 24 Hillhouse Avenue >> New Haven, CT 06520 >> >> e-mail: [hidden email] >> >> ______________________________________________ >> [hidden email] mailing list >> https://stat.ethz.ch/mailman/listinfo/r-devel >> >> > > ______________________________________________ > [hidden email] mailing list > https://stat.ethz.ch/mailman/listinfo/r-devel ______________________________________________ [hidden email] mailing list https://stat.ethz.ch/mailman/listinfo/r-devel |
|
On Jan 11, 2012, at 1:04 PM, Uwe Ligges wrote: > > > On 11.01.2012 18:49, Simon Urbanek wrote: >> >> On Jan 11, 2012, at 12:08 PM, Taylor Arnold wrote: >> >>> R-devel, >>> >>> I have noticed that making a copy of an object in R prior to using >>> .Call on the original object can >>> cause the C code to alter not only the object passed to it but also >>> the copy in R. >> >> Please see the docs - .Call does *NOT* have a DUP argument - you are responsible for duplication at all times if you make modifications (e.g. using duplicate()). >> >> Cheers, >> Simon >> >> >>> A simple example >>> is: >>> >>>> x<- 2 >>>> y<- x >>>> .Call("addOne", x, DUP=TRUE) # Changing DUP does not alter output >>> NULL >>>> x >>> [1] 3 >>>> y >>> [1] 3 >>> >>> And corresponding simple C code: >>> >>> "test.c": >>> #include<R.h> >>> #include<Rinternals.h> >>> #include<Rmath.h> >>> >>> SEXP addOne(SEXP input) { >>> REAL(input)[0] = REAL(input)[0] + 1; >>> return R_NilValue; >>> } >>> >>> I assume that this is simply a result of lazy loading > > In addition to Simon: it is "lazy evalution" rather than lazy loading in this case. > It is actually neither. `x` gets evaluated, but the value is shared with `y` because R has no reason to create a copy of identical information until modified. That's why the .Call() code must create a copy if it wants to touch the value that it received. Note that .Call does *not* get `x` itself - it gets a value obtained from the binding of `x` so the only legal way to modify `x` is to assign a value to it. You can try to be more efficieint and check if a value has references to it and prevent copying if it doesn't (see NAMED), but if it does, you have to copy it. Cheers, Simon > Uwe > > >>> in R, and well >>> documented. My question is, do >>> there exist functions to (1) force R to make a copy of an object >>> (force() does not work), and (2) to check >>> whether two objects are actually pointing to the same memory address. >>> For question 1, I have >>> found specific operations which force a copy of a given datatype, but >>> would prefer a more general >>> solution. >>> >>> Thank you, >>> >>> Taylor >>> >>>> sessionInfo() >>> R version 2.14.1 (2011-12-22) >>> Platform: x86_64-apple-darwin9.8.0/x86_64 (64-bit) >>> >>> locale: >>> [1] en_GB.UTF-8/en_GB.UTF-8/en_GB.UTF-8/C/en_GB.UTF-8/en_GB.UTF-8 >>> >>> attached base packages: >>> [1] stats graphics grDevices utils datasets methods base >>> >>> loaded via a namespace (and not attached): >>> [1] tools_2.14.1 >>> >>> >>> -- >>> Taylor B. Arnold >>> Department of Statistics >>> Yale University >>> 24 Hillhouse Avenue >>> New Haven, CT 06520 >>> >>> e-mail: [hidden email] >>> >>> ______________________________________________ >>> [hidden email] mailing list >>> https://stat.ethz.ch/mailman/listinfo/r-devel >>> >>> >> >> ______________________________________________ >> [hidden email] mailing list >> https://stat.ethz.ch/mailman/listinfo/r-devel > > ______________________________________________ [hidden email] mailing list https://stat.ethz.ch/mailman/listinfo/r-devel |
| Powered by Nabble | Edit this page |
