<br><br><div class="gmail_quote">On Thu, Oct 28, 2010 at 6:04 PM, Douglas Bates <span dir="ltr"><<a href="mailto:bates@stat.wisc.edu">bates@stat.wisc.edu</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt 0.8ex; border-left: 1px solid rgb(204, 204, 204); padding-left: 1ex;">
<div><div></div><div class="h5">On Thu, Oct 28, 2010 at 1:44 PM, Dominick Samperi <<a href="mailto:djsamperi@gmail.com">djsamperi@gmail.com</a>> wrote:<br>
> See comments on Rcpp below.<br>
><br>
> On Thu, Oct 28, 2010 at 11:28 AM, William Dunlap <<a href="mailto:wdunlap@tibco.com">wdunlap@tibco.com</a>> wrote:<br>
>><br>
>> > -----Original Message-----<br>
>> > From: <a href="mailto:r-devel-bounces@r-project.org">r-devel-bounces@r-project.org</a><br>
>> > [mailto:<a href="mailto:r-devel-bounces@r-project.org">r-devel-bounces@r-project.org</a>] On Behalf Of Andrew Piskorski<br>
>> > Sent: Thursday, October 28, 2010 6:48 AM<br>
>> > To: Simon Urbanek<br>
>> > Cc: <a href="mailto:r-devel@r-project.org">r-devel@r-project.org</a><br>
>> > Subject: Re: [Rd] must .Call C functions return SEXP?<br>
>> ><br>
>> > On Thu, Oct 28, 2010 at 12:15:56AM -0400, Simon Urbanek wrote:<br>
>> ><br>
>> > > > Reason I ask, is I've written some R code which allocates two long<br>
>> > > > lists, and then calls a C function with .Call. My C code<br>
>> > writes to<br>
>> > > > those two pre-allocated lists,<br>
>> ><br>
>> > > That's bad! All arguments are essentially read-only so you should<br>
>> > > never write into them!<br>
>> ><br>
>> > I don't see how. (So, what am I missing?) The R docs themselves<br>
>> > state that the main point of using .Call rather than .C is that .Call<br>
>> > does not do any extra copying and gives one direct access to the R<br>
>> > objects. (This is indeed very useful, e.g. to reorder a large matrix<br>
>> > in seconds rather than hours.)<br>
>> ><br>
>> > I could allocate the two lists in my C code, but so far it was more<br>
>> > convenient to so in R. What possible difference in behavior can there<br>
>> > be between the two approaches?<br>
>><br>
>> Here is an example of how you break the rule that R-language functions<br>
>> do not change their arguments if you use .Call in the way that you<br>
>> describe. The C code is in alter_argument.c:<br>
>><br>
>> #include <R.h><br>
>> #include <Rinternals.h><br>
>><br>
>> SEXP alter_argument(SEXP arg)<br>
>> {<br>
>> SEXP dim ;<br>
>> PROTECT(dim = allocVector(INTSXP, 2));<br>
>> INTEGER(dim)[0] = 1 ;<br>
>> INTEGER(dim)[1] = LENGTH(arg) ;<br>
>> setAttrib(arg, R_DimSymbol, dim);<br>
>> UNPROTECT(1) ;<br>
>> return dim ;<br>
>> }<br>
>><br>
>> Make a shared library out of this. E.g., on Linux do<br>
>> R CMD SHLIB -o Ralter_argument.so alter_argument.so<br>
>> and load it into R with<br>
>> dyn.open("./Ralter_argument.so")<br>
>> (Or, on any platform, put it into a package along with<br>
>> the following R code and build it.)<br>
>><br>
>> The associated R code is<br>
>> myDim <- function(v).Call("alter_argument", v)<br>
>> f <- function(z) myDim(z)[2]<br>
>> Now try using it:<br>
>> > myData <- 6:10<br>
>> > myData<br>
>> [1] 6 7 8 9 10<br>
>> > f(myData)<br>
>> [1] 5<br>
>> > myData<br>
>> [,1] [,2] [,3] [,4] [,5]<br>
>> [1,] 6 7 8 9 10<br>
>> The argument to f was changed! This should never happen in R.<br>
>><br>
>> If you are very careful you might be able ensure that<br>
>> no part of the argument to be altered can come from<br>
>> outside the function calling .Call(). It can be tricky<br>
>> to ensure that, especially when the argument is more complicated<br>
>> than an atomic vector.<br>
>><br>
>> "If you live outside the law you must be honest" - Bob Dylan.<br>
><br>
> This thread seems to suggest (following Bob Dylan) that one needs<br>
> to be very careful when using C/C++ to modify R's memory<br>
> directly, because you may modify other R variables that point<br>
> to the same memory (due to R's copy-by-value semantics and<br>
> optimizations).<br>
><br>
> What are the implications for the Rcpp package where R<br>
> objects are exposed to the C++ side in precisely this way,<br>
> permitting unrestricted modifications? (In the original<br>
> or "classic" version of this package direct writes to R's<br>
> memory were done only for performance reasons.)<br>
><br>
> Seems like extra precautions need to be taken to<br>
> avoid the aliasing problem.<br>
<br>
</div></div>The current Rcpp facilities has the same benefits and dangers as the C<br>
macros used in .Call. You get access to the memory of the R object<br>
passed as an argument, saving a copy step. You shouldn't modify that<br>
memory. If you do, bad things can happen and they will be your fault.<br>
If you want to get a read-write copy you clone the argument (in Rcpp<br>
terminology).<br>
<br>
To Bill: I seem to remember the Dylan quote as "To live outside the<br>
law you must be honest."<br></blockquote><div><br>And There are No Truths Outside the Gates of Eden.<br><br>Cool, a Dylan thread...<br><br></div></div>