[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