Vadim Ogranovich
2004-Mar-06 06:26 UTC
[R] .Call: is new attribute of protected object auto-protected
Hi, I have an SEXP obj in a C function called via .Call(). The obj is protected (in fact it is an argument to .Call and therefore automatically protected). If I set an attribute of obj does the attribute become protected too? Here is an example SEXP foo(SEXP obj) { SET_NAMES(obj, NEW_CHARACTER(3)); /* are names protected or not? */ ... } Thanks, Vadim [[alternative HTML version deleted]]
Prof Brian Ripley
2004-Mar-06 08:02 UTC
[R] .Call: is new attribute of protected object auto-protected
One again, please read the source code to find out. You are using the Rdefines.h back-compatibility macros that very few of us use and so almost all of your audience has no idea exactly what they do (nor AFAIK is that documented anywhere). We would have to read the source code for you, and that is unreasonable. Since the names<- function does this in R, this should be easy for you to ascertain. Note that most of these replacement functions are not quite the same as setting an attribute, and indeed setting some attributes (including "names") have special-purpose code. So your example is potentially not an example of your subject line. On Fri, 5 Mar 2004, Vadim Ogranovich wrote:> I have an SEXP obj in a C function called via .Call(). The obj is > protected (in fact it is an argument to .Call and therefore > automatically protected). If I set an attribute of obj does the > attribute become protected too? Here is an example > > SEXP foo(SEXP obj) { > SET_NAMES(obj, NEW_CHARACTER(3)); /* are names protected or not? */ > ... > }-- Brian D. Ripley, ripley at stats.ox.ac.uk 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
Douglas Bates
2004-Mar-06 13:28 UTC
[R] .Call: is new attribute of protected object auto-protected
"Vadim Ogranovich" <vograno at evafunds.com> writes:> I have an SEXP obj in a C function called via .Call(). The obj is > protected (in fact it is an argument to .Call and therefore > automatically protected). If I set an attribute of obj does the > attribute become protected too? Here is an example > > SEXP foo(SEXP obj) { > SET_NAMES(obj, NEW_CHARACTER(3)); /* are names protected or not? */ > ... > }Yes. I use that property extensively when I am writing code for the .Call interface. Take a look at the C code in the Matrix package for r-devel (available in the src/contrib/1.9.0 directory on CRAN) and you will see that in most functions that return an SEXP I create and PROTECT the value to be returned then do all the other allocations within SET_SLOT or setAttrib or SET_VECTOR_ELT. This results in a lot of what may be slightly strange looking code like SEXP val = PROTECT(NEW_OBJECT(MAKE_CLASS("myclass"))); int n; double *realslot; ... SET_SLOT(val, install("slotname"), allocVector(REALSXP, n)); realslot = REAL(GET_SLOT(val, install("slotname"))); ... /* do something to the elements of the realslot vector here */ UNPROTECT(1); return val; It looks a bit strange because I am getting the slot immediately after setting it. (There are ways around this involving saving some temporary results but I find them more confusing to read.) The important point is that I set the slot directly on allocating so that the value of the allocation is protected and I don't have to PROTECT and UNPROTECT it explicitly. I find that having to keep track of how many objects I have protected is a source of errors for me so I try to ensure that I only PROTECT one object and do all allocations as components of that object. Usually I can manage to count up to 1 without making mistakes :-)