sidebarpanel div app r warnings rcpp longjmp

div - Cómo generar una advertencia R de forma segura en Rcpp



sidebarpanel shiny (2)

Recomendaría usar stop() (que es un envoltorio alrededor de try/catch ) en su lugar:

Con su código ligeramente modificado:

#include <Rcpp.h> using namespace Rcpp; class Test { public: Test() { Rcout << "start/n"; } ~Test() { Rcout << "end/n"; } }; // [[Rcpp::export]] void test() { Test t; Rf_warning("test"); } // [[Rcpp::export]] void test2() { Test t; stop("test2"); } /*** R options(warn=10) #test() test2() */

Me sale el comportamiento deseado:

R> sourceCpp("/tmp/throw.cpp") R> options(warn=10) R> #test() R> test2() start end Error in eval(expr, envir, enclos) (from srcConn#3) : test2 R>

El problema de longjmp es conocido, pero no gana al evitar los mecanismos que tenemos para desenrollar objetos.

Sabemos que llamar a Rf_error() debe evitarse en Rcpp, ya que implica un longjmp sobre los destructores de C ++ en la pila. Esta es la razón por la que preferimos lanzar excepciones C ++ en el código Rcpp (como throw Rcpp::exception("...") o mediante la función de stop("...") ).

Sin embargo, las advertencias R también pueden resultar en una llamada a Rf_error() (este comportamiento depende de la opción de warn ). Por lo tanto, una llamada a Rf_warning() también es arriesgada.

Rcpp::sourceCpp(code = '' #include <Rcpp.h> using namespace Rcpp; class Test { public: Test() { Rcout << "start//n"; } ~Test() { Rcout << "end//n"; } }; // [[Rcpp::export]] void test() { Test t; Rf_warning("test"); } '') options(warn=10) test() ## start ## Error in test() : (converted from warning) test

Vemos que no se ha llamado al destructor (no hay un mensaje de "fin").

¿Cómo generar una advertencia de R en una forma C ++, de una manera amigable para el destructor?


Una de las soluciones que encontré involucra llamar a la función de warning de R desde Rcpp:

// [[Rcpp::export]] void test() { Test t; Function warning("warning"); warning("test"); // here R errors are caught and transformed to C++ exceptions }

que da el comportamiento correcto si warn>2 :

start end Error in eval(expr, envir, enclos) : (converted from warning) test

Me pregunto si alguien tiene una mejor idea para eso.