如何在 Rcpp 中安全地生成 R 警告 [英] How to generate an R warning safely in Rcpp

查看:47
本文介绍了如何在 Rcpp 中安全地生成 R 警告的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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 Rcpp code (like throw Rcpp::exception("...") or via the stop("...") function).

然而,R 警告也可能导致调用 Rf_error()(此行为取决于 warn 选项).因此,调用 Rf_warning() 也是有风险的.

However, R warnings may also result in a call to Rf_error() (this behavior depends on the warn option). So, a call to Rf_warning() is also risky.

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

我们看到析构函数没有被调用(没有结束"消息).

We see that the destructor hasn't been called (there's no "end" message).

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

How to generate an R warning in a C++-destructor-friendly way?

推荐答案

我提出的解决方案之一涉及从 Rcpp 调用 R 的 warning 函数:

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
}

如果 warn>2 给出正确的行为:

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.

这篇关于如何在 Rcpp 中安全地生成 R 警告的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆