Thank you very much, that was very helpful. Now I think I understand (parts of) the protection mechanism.
/Kasper On May 23, 2006, at 9:03 PM, Prof Brian Ripley wrote: > On Tue, 23 May 2006, Kasper Daniel Hansen wrote: > >> Thank you very much. I think I do have a clearer understanding, >> but I have a few questions >> >> On May 23, 2006, at 12:55 AM, Prof Brian Ripley wrote: >> >>> On Tue, 23 May 2006, Prof Brian Ripley wrote: >>>> On Mon, 22 May 2006, Kasper Daniel Hansen wrote: >>>>> I have a few simple questions about the usage of PROTECT, more >>>>> specifically how careful one needs to be. Simple yes/no answers >>>>> are >>>>> fine. >>>> (Except that in the last case they would be misleading.) >>>>> Most of the uses I have seen do protection when memory is >>>>> allocated. >>>>> But what if one just want to assign a value of another function >>>>> to a >>>>> variable. Say eg. that foo is a function that returns a SEXP. >>>>> Would >>>>> the following code be fine? >>>>> SEXP bar; >>>>> PROTECT(bar = foo()); >>>> It would be fine but may be unnecessary. It is objects and not >>>> pointers >>>> which are protected, and a SEXP is a pointer. So protection is >>>> needed >>>> only if foo() might return a pointer to an unprotected object. >> >> Ok. I have been coding foo in such a way that I unprotect >> everything in foo just before returning its value. I thought that >> was the "standard" way to do - is that true? Or should I leave the >> return value protected and then unprotect in the function calling >> foo? > > That is indeed standard. The issue is rather that if say foo() > extracts an element of a list which has an R-level name, you know > that it is already protected. > >>>>> Also, basically in one use case I would want to return the >>>>> value of >>>>> foo immediately, but I need to do some cleaning up first, which >>>>> has >>>>> nothing to do with R (more specifically, I need to close various >>>>> files). Would I then need to protect foo, as in >>>>> SEXP bar; >>>>> bar = foo(); >>>>> "close the file in C++" >>>>> return bar; >>>> Fine, as PROTECT protects against R garbage collection, and that >>>> can only >>>> happen if R's functions are called. >>>>> Finally, I am also assigning values to the components of a list. >>>>> Would the following be ok >>>>> SEXP bar; >>>>> PROTECT(bar = NEW_LIST(2)); >>>>> SET_VECTOR_ELT(bar, 0, ScalarInteger(test()); >>>>> (where test is a function returning int, which again has >>>>> nothing to >>>>> do with R - it interfaces to an extern library), or do I need to >>>>> hedge myself against garbage collection in the SET_VECTOR_ELT >>>>> macro? >>>> You do need to protect but elsewhere in this call, as >>>> ScalarInteger does >>>> memory allocation: >>>> INLINE_FUN SEXP ScalarInteger(int x) >>>> { >>>> SEXP ans = allocVector(INTSXP, 1); >>>> INTEGER(ans)[0] = x; >>>> return ans; >>>> } >>>> but SET_VECTOR_ELT does not. So you need >>>> SEXP bar, tmp; >>>> PROTECT(bar = NEW_LIST(2)); >>>> PROTECT(tmp = test()); >>>> SET_VECTOR_ELT(bar, 0, ScalarInteger(tmp)); >>>> UNPROTECT(1); >>> Or a design that uses fewer PROTECTs >>> SEXP bar, tmp; >>> PROTECT(bar = allocVector(VECSXP, 2)); >>> tmp = allocVector(INTSXP, 1); >>> SET_VECTOR_ELT(bar, 0, tmp); >>> INTEGER(tmp)[0] = test(); >> >> I thought I got this. Then I grepped the sources and found this in >> main/platform.c: >> >> PROTECT(ans = allocVector(VECSXP, 18)); >> PROTECT(nms = allocVector(STRSXP, 18)); >> SET_STRING_ELT(nms, 0, mkChar("double.eps")); >> SET_VECTOR_ELT(ans, 0, ScalarReal(R_AccuracyInfo.eps)); >> >> This looks very similar to what I did above. In my case "test" was >> a C++ function coming from outside of R returning an int. That was >> perhaps not clear from my original mail, since the first suggested >> correction had >> PROTECT(tmp = test()); >> indicating that the return value for test is a SEXP. Or am I >> completely of? > > If test() iself does not use anthing from R (that it is C++ is > enough of the story), then you do not need to protect it. Or as in > the platform.c example, if it is a constant. Sorry, the caveats > were not clear to me, and I tend not to rely on them as people do > sometimes change functions. > >> I have tried running my original suggestion with gctorture(TRUE) >> and it did not give any errors. But neither did the second >> suggested correction. > > > -- > Brian D. Ripley, [EMAIL PROTECTED] > Professor of Applied Statistics, http://www.stats.ox.ac.uk/~ripley/ > University of Oxford, Tel: +44 1865 272861 (self) > 1 South Parks Road, +44 1865 272866 (PA) > Oxford OX1 3TG, UK Fax: +44 1865 272595 ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel