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