首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Rcpp中安全生成R警告

如何在Rcpp中安全生成R警告
EN

Stack Overflow用户
提问于 2014-07-03 15:25:25
回答 2查看 3.1K关注 0票数 21

我们知道在Rcpp中应该避免调用Rf_error(),因为它涉及堆栈上的C++析构函数之上的长C++。这就是为什么我们宁愿在Rcpp代码中抛出C++异常(比如throw Rcpp::exception("...")或通过stop("...")函数)。

但是,R警告也可能导致对Rf_error()的调用(此行为取决于warn选项)。因此,打电话给Rf_warning()也是有风险的。

代码语言:javascript
复制
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

我们看到未调用析构函数(没有“结束”消息)。

如何以C++-析构函数友好的方式生成R警告?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-07-03 15:30:26

我想出的解决方案之一是从Rcpp调用R的warning函数:

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

它提供了正确的行为,如果warn>2

代码语言:javascript
复制
start
end
Error in eval(expr, envir, enclos) : (converted from warning) test

我想知道是否有人对此有更好的想法。

票数 14
EN

Stack Overflow用户

发布于 2014-07-03 15:32:51

我建议使用stop() (它是try/catch的包装器)来代替:

对代码稍加修改:

代码语言:javascript
复制
#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()
*/

我得到了想要的行为:

代码语言:javascript
复制
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> 

longjmp问题是众所周知的,但您不能通过避免我们必须解除对象的机制而获胜。

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24557711

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档