How to generate an R warning safely in Rcpp

后端 未结 2 1395
一个人的身影
一个人的身影 2021-02-07 04:25

We know that calling Rf_error() should be avoided in Rcpp as it involves a longjmp over C++ destructors on the stack. This is why we rather throw C++ exceptions in

相关标签:
2条回答
  • 2021-02-07 05:02

    One of the solutions I came up with involves calling the R's warning function from Rcpp:

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

    which gives the correct behavior if warn>2:

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

    I wonder if anybody has a better idea for that.

    0 讨论(0)
  • 2021-02-07 05:23

    I would recommend using stop() (which is a wrapper around try/catch) instead:

    With your code slightly modified:

    #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()
    */
    

    I get the desired behaviour:

    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> 
    

    The longjmp issue is known, but you do not win by avoiding the mechanisms we have to unwind objects.

    0 讨论(0)
提交回复
热议问题