From simon.urbanek at r-project.org  Wed Jan 11 19:21:05 2012
From: simon.urbanek at r-project.org (Simon Urbanek)
Date: Wed, 11 Jan 2012 13:21:05 -0500
Subject: [Rd] Copying objects prior to .Call
In-Reply-To: <4F0DCF1C.60005@statistik.tu-dortmund.de>
References: <CAM3Zkc4WuKMKS-CSCu2yYnqkEzZ=_39awBOyAa=H=_DY-U1YeA@mail.gmail.com>
	<B3877BB6-1156-4BD1-8B13-3EE2D3F81ABF@r-project.org>
	<4F0DCF1C.60005@statistik.tu-dortmund.de>
Message-ID: <7EEE1F9F-A6B2-4885-9FC0-09C90164FBB4@r-project.org>


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: 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
Simon Urbanek