From bates at stat.wisc.edu  Wed Jan 11 19:03:24 2012
From: bates at stat.wisc.edu (Douglas Bates)
Date: Wed, 11 Jan 2012 12:03:24 -0600
Subject: [Rd] Copying objects prior to .Call
In-Reply-To: <B3877BB6-1156-4BD1-8B13-3EE2D3F81ABF@r-project.org>
References: <CAM3Zkc4WuKMKS-CSCu2yYnqkEzZ=_39awBOyAa=H=_DY-U1YeA@mail.gmail.com>
	<B3877BB6-1156-4BD1-8B13-3EE2D3F81ABF@r-project.org>
Message-ID: <CAO7JsnRvgwUSX=qwTByHMVhy5fYEh=FXh4-Q0gQRcBEp6PBQ5g@mail.gmail.com>

On Wed, Jan 11, 2012 at 11:49 AM, Simon Urbanek
<simon.urbanek at r-project.org> 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: taylor.arnold at yale.edu
>>
>> ______________________________________________
>> R-devel at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>
>>
>
> ______________________________________________
> R-devel at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel



[Rd] Copying objects prior to .Call
Douglas Bates