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