On Sep 15, 2012, at 11:28 AM, Simon Knapp wrote:

> Hi Simon,
> 
> Thanks for your advice, but I'm still not clear. In my case I don't
> want to modify the result - the integer acts as a handle for indexing
> an array in later calls back into my library.
> 
> As I understand it, returning result like
> 
> SEXP func(SEXP arg) {return arg;}
> 
> would not copy arg and hence I would have two pointers to the same
> object immediately after the call... and (if this is the case) I'm not
> sure whether this is OK.
> 

My answer is was, yes, it's ok.


> Just to be clear, are you saying that the proper way to do things is
> (at the end of my function in the original post):
> 
> SET_SLOT(ans, Rf_install("myInteger"), duplicate(thingysInteger));
> return ans;
> 
> rather than
> 
> SET_SLOT(ans, Rf_install("myInteger"), thingysInteger);
> return ans;
> 
> ?
> 

No, because you're not modifying anything in that case.


> The last thing I'm not clear on is if it is OK to create a new SEXP
> (with a call like duplicate) in a call to another function (as in the
> first case above) or does this leave it unprotected?
> 

Most functions (but not all - a notable exception is eval) protect their 
arguments, so it's ok in most cases. But this is no different than any other 
SEXP result - not specific to duplicate() in particular.

Cheers,
Simon



> Thanx again for your help,
> Simon
> 
> On Sat, Sep 15, 2012 at 10:40 PM, Simon Urbanek
> <simon.urba...@r-project.org> wrote:
>> 
>> On Sep 14, 2012, at 11:10 PM, Simon Knapp wrote:
>> 
>>> Hi List,
>>> 
>>> I'd imagine this is a question that has been answered before, but I
>>> can't seem to track it down, sorry for the duplication if it has.
>>> 
>>> I am writing an interface for a C library and want to return an S4
>>> class from the 'constructing' method. One of the slots of the argument
>>> to be returned will be filled with one of the arguments passed to the
>>> function. My question is about whether I can directly pass arguments
>>> to the function directly to slots of the returned object (or to a
>>> return value more generally for that matter), or whether I have to
>>> copy them. If it is the latter, then how may I do this. The question
>>> is phrased in the following (simplified) code.
>>> 
>>> int constructThingy(int thingysInteger);
>>> 
>>> SEXP constructThingy(SEXP thingysInteger) {
>>>   SEXP ans, TClass, ti;
>>>   if(!isInteger(thingysInteger)) error("thingysIntegermust be an integer.");
>>>   if(constructThingy(INTEGER(thingysInteger)[0])) error("error in
>>> getting a thingy");
>>>   TClass = MAKE_CLASS("thingy");
>>>   PROTECT(ans = NEW_OBJECT(TClass));
>>> 
>>> 
>>>   // *****QUESTION STARTS HERE*****
>>>   // CAN I SAY:
>>>   SET_SLOT(ans, Rf_install("myInteger"), thingysInteger);
>>> 
>>>   // IF NOT, CAN I SAY
>>>   SET_SLOT(ans, Rf_install("myInteger"), AS_INTEGER(thingysInteger));
>>> 
>>>   // OR DO I NEED TO SAY
>>>   PROTECT(ti = allocVector(INTSXP, 1)); INTEGER(pns)[0] =
>>> INTEGER(thingysInteger)[0];
>>>   SET_SLOT(ans, Rf_install("myInteger"), ti);
>>>   // *****END OF QUESTION*****
>>> 
>>>   UNPROTECT(1); // or UNPROTECT(2) in latter case.
>>>   return ans;
>>> }
>>> 
>>> 
>>> 
>>> I think this is the same as asking whether the following is OK:
>>> 
>>> SEXP func(SEXP arg) {
>>>   return arg;
>>> }
>>> 
>> 
>> Yes.
>> 
>> In fact if you wanted to duplicate (e.g, if you want to modify an incoming 
>> argument and return the modified result), the proper way would be to use 
>> duplicate() and not the contortions your were trying.
>> 
>> Cheers,
>> Simon
>> 
>> 
>>> 
>>> 
>>> 
>>> 
>>> Thanks in advance,
>>> Simon
>>> 
>>> ______________________________________________
>>> R-devel@r-project.org mailing list
>>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>> 
>>> 
>> 
> 
> 

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to