[Rcpp-devel] Armor, Shield and Shelter.

Romain Francois romain at r-enthusiasts.com
Fri Oct 11 13:03:07 CEST 2013


Hello,

As usual when I work on some packge that use Rcpp, I come up with ideas. 
On dplyrRcpp I've defined these classes to handle stack based protection 
of objects from the GC. These are thin wrappers around PROTECT / 
UNPROTECT / PROTECT_WITH_INDEX

Sometimes, the Rcpp api classes don't quite cut it and one has to 
directly manipulate SEXP. When we do that we have to surrender to use 
the ugly PROTECT/UNPROTECT macros and whenever I use them, I feel 
unsafe, because later on I will forget to correctly unprotect, ...

Anyway, I'd like to propose adding Shield, Armor and Shleter to Rcpp. 
For now they live in the tools directory of dplyrRcpp.

Shield
======

That is simplest. When a Shield object is constructed, PROTECT is 
called, when it is destructed UNPROTECT(1) is called. Using it looks 
like this:

Shield<SEXP> x( ... ) ;

Shield has a conversion to SEXP operator that returns its SEXP so we can 
pass a Shield<SEXP> to any function that takes a SEXP.

Armor
=====

This is similar but it uses the less known PROTECT_WITH_INDEX and 
REPROTECT.

It should be preferred to Shield when we change the object we want to 
protect, for example in a loop.

When it is constructed, it protects its SEXP and records its index in 
the protection stack, when something is assigned to it, the new object 
takes its place so the previously protected object might no longer be.

Armor<SEXP> x( ... ) ;
x = ... ;


Shelter
=======

Shelter is a bit different as it protects several objects in the same 
scope. It has an function call like operator that protects its argument 
and bumps up the number of objects it currently protects. Whe it is 
destructed, it unprotects that many objects.

Looks like this for now:

Shelter<SEXP> ___ ;
SEXP x = ___(...) ;

There are cases when this is useful and for which I could not use either 
Armor or Shield. They are used throughout dplyrRcpp and it makes perfect 
sense to use them. That's another clear win of C++ against macros.



They are all templated, but it really only makes sense to use SEXP as 
the parameter, maybe I'll enforce that. It just looks nice to me:

Shield<SEXP>
Armor<SEXP>
Shekter<SEXP>

It conveys the idea of protecting a SEXP.


I will add them to Rcpp11, and I would like to add them to Rcpp too. So 
I wanted to start a discussion on them here.

With these, we should never need to call PROTECT / UNPROTECT macros ...

Please let me know what you think about that. Getting no reply means 
"nobody cares", so please comment on this if you want to see them in Rcpp.

This is starting to be the way I approach contributing to Rcpp, start a 
discussion on a feature and add it if people care. This is somewhat 
different from the approach I used to take which was put the code in 
anyway and let people know afterwards.

This is a non disruptive proposal as the template classes I propose 
don't interract with the rest of the code. We might not use them in 
Rcpp, but we should. There are currently 155 calls to UNPROTECT in the 
.h and .cpp of Rcpp. That is that many macro calls we could get rid of.

Romain

-- 
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30



More information about the Rcpp-devel mailing list