[Rcpp-devel] Rf_error and Rcpp

Romain Francois romain at r-enthusiasts.com
Tue May 4 18:02:48 CEST 2010


Le 04/05/10 15:18, Douglas Bates a écrit :
> After following some of the discussion in that thread I was going to
> ask exactly the question that you just answered.

Please note that I discovered the issue with the thread so what I say 
might not reflect what would someone with Simon's experience know ...

> On Tue, May 4, 2010 at 2:35 AM, Romain Francois
> <romain at r-enthusiasts.com>  wrote:
>> Hello,
>>
>> One crucial nugget of information from somewhere in this R-devel thread:
>> http://article.gmane.org/gmane.comp.lang.r.devel/24284
>>
>> When using c++ --- and therefore Rcpp --- it is not safe to call Rf_error to
>> stop the c function because error seems to bypass c++ unwinding and might
>> leave c++ in an inconsistent state where objects are not properly deleted,
>> etc ...
>>
>> Therefore the recommendation I would promote is to :
>> - wrap each function by BEGIN_RCPP and END_RCPP (which will arrive with
>> 0.8.0)
>> - use exceptions instead of errors
>>
>> Something like this:
>>
>> SEXP foobar( SEXP x_, SEXP y_){
>>         BEGIN_RCPP
>>         std::vector<int>  z(3);
>>         int x = Rcpp::as<int>(x_) ;
>>         double y = Rcpp::as<double>(y_) ;
>>         if( x<  0 ) throw std::range_error("no good");
>>         END_RCPP
>>         return Rcpp::wrap( 3 ) ;
>> }
>>
>> This can be facilitated by the new RCPP_* macros:
>>
>> RCPP_FUNCTION_2( int, foobar, int x, double y){
>>         std::vector<int>  z(3) ;
>>         if( x<  0 ) throw std::range_error("no good");
>>         return 3 ;
>> }
>>
>> because this exit the flow through c++ exceptions, this will properly unwind
>> the stack and therefore deal with z. From what I understand of Simon's
>> emails in R-devel, using Rf_error here instead of throw would not delete z.
>>
>> I'm sending this here because I seem to recall people mixing C++ and error
>> (no documentation says one should not anyway) but I don't remember where
>> (maybe minqa or lme4a).
>
> Both, it turns out.  I will provide a new version of minqa when Rcpp
> 0.8.0 is released (so that I can list a dependency on Rcpp (>=0.8.0)).
>   Meanwhile I will revise the code in lme4a, which is a development
> version and never formally released.
>
> As I understand it, we are still at risk of code in the R API that we
> call in turn calling Rf_error, right?  That will have the same effect
> of leaving the C++ exception stack in an inconsistent state?

Yes. While we do our best to isolate this problem, it is still a 
possibility.

We need to track down all calls to R APIs in Rcpp and be careful about 
potential jumps. This is probably going to be difficult to track, fix or 
even test that we fixed it, because apparently the incubating period is 
unpredictable (if I understand what Simon wrote) and the symptoms could 
be quite unrelated. should be fun.

One thing I am not sure at all is how the old api behaves with regards 
to exceptions and R error mechanism, and I'm not volunteering to look.

Romain

-- 
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30
http://romainfrancois.blog.free.fr
|- http://bit.ly/9aKDM9 : embed images in Rd documents
|- http://tr.im/OIXN : raster images and RImageJ
|- http://tr.im/OcQe : Rcpp 0.7.7



More information about the Rcpp-devel mailing list