Le 19 juin 2014 à 01:02, Tim Keitt <tke...@utexas.edu> a écrit :

> 
> 
> 
> On Wed, Jun 18, 2014 at 5:37 PM, Romain Francois <rom...@r-enthusiasts.com> 
> wrote:
> Le 19 juin 2014 à 00:30, Tim Keitt <tke...@utexas.edu> a écrit :
> 
>> On Wed, Jun 18, 2014 at 5:22 PM, Romain Francois <rom...@r-enthusiasts.com> 
>> wrote:
>> Le 19 juin 2014 à 00:15, Tim Keitt <tke...@utexas.edu> a écrit :
>> 
>> 
>>> 
>>> On Wed, Jun 18, 2014 at 5:07 PM, Romain Francois <rom...@r-enthusiasts.com> 
>>> wrote:
>>> Le 18 juin 2014 à 23:54, Tim Keitt <tke...@utexas.edu> a écrit :
>>> 
>>> 
>>>> I'd like to raise a condition other than error or warning. Is that 
>>>> possible using the Rcpp api? I assume this can be done via R internals, 
>>>> but I'd prefer not to call error() directly (or is that the 
>>>> recommendation?).
>>>> 
>>>> THK
>>> 
>>> Definitely not. Rf_error should really only be called from C code. If you 
>>> call it from C++, there is a great chance you'll lose determinism as 
>>> destructors for your c++ objects are very likely not to be called. Most of 
>>> the time, it will just mean you'll never release some objects to the 
>>> garbage collector, but it could also get you leaks or other nice stuff 
>>> depending on what your destructors were supposed to do and did not get a 
>>> chance to do.  
>>> 
>>> That was my understanding. Just wanted to be sure it was still the case.
>>>  
>>> 
>>> I'm not sure Rcpp has a way to raise an R condition apart from calling 
>>> stop, which usually is good enough. Otherwise, you can borrow from Rcpp11 
>>> and adapt some code from 
>>> https://github.com/Rcpp11/Rcpp11/blob/450aade7338c16c34618ad0916003e8ca4fb58a6/inst/include/Rcpp/Condition.h
>>> 
>>> Ah. I see. Eval "stop" in the global env with the condition as the 
>>> argument. Clever.
>> 
>> It is more of a hack due to lack of proper api from R. 
>> 
>> If you do this, make sure you don't have any c++ object in scope. 
>> Essentially that means you would evaluate `stop( condition )` in a top level 
>> catch block. 
>> 
>> Rcpp objects are I assume ok however.
> 
> Depends what you mean by "ok". If you mean objects like NumericVector, ... 
> their destructor is responsible for calling R_ReleaseObject, i.e. let go of 
> the protection that was set by their constructor. If the destructor is not 
> called because R error handling does a long jump, you will get objects 
> forever protected. 
> 
> So things will seemingly work, until you exhaust the memory. 
> 
>> I will try "signalCondition" and see what happens.
>> 
>> THK
> 
> 
> I can't get signalCondition to do anything.

What exactly did you try ? Did you catch the condition at the R level, with 
withCallingHandlers or something. Just because you don't see something does not 
mean nothing happens. 

> This works although I've not tested it for leaks.

Easy enough to test for forgotten destructors. 

#include <Rcpp.h>
using namespace Rcpp; 

void raise_condition(const std::string& msg,
                     const std::string& type)
{
  List cond;
  cond["message"] = msg;
  cond["call"] = R_NilValue;
  cond.attr("class") = CharacterVector::create(type, "condition");
  Function stopper("stop");
  stopper(cond);
}

class A {
   public:
       A(){ Rprintf( "A::A()\n" ) ; }
       ~A(){ Rprintf( "A::~A()\n" ) ; }
} ;


// [[Rcpp::export]]
void test(){
    A a ;
    raise_condition( "foo", "bar") ;  
}

/*** R
    test()
*/

which gives me:

>     test()
A::A()
Error: foo

So the destructor for A is never called. Not a big deal here, it was not doing 
anything. But might be more problematic elsewhere. 

> void raise_condition(const std::string& msg,
>                      const std::string& type)
> {
>   List cond;
>   cond["message"] = msg;
>   cond["call"] = R_NilValue;
>   cond.attr("class") = CharacterVector::create(type, "condition");
>   Function stopper("stop");
>   stopper(cond);
> }
> 
> THK
> 
> -- 
> http://www.keittlab.org/

_______________________________________________
Rcpp-devel mailing list
Rcpp-devel@lists.r-forge.r-project.org
https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel

Reply via email to