问题描述
我们知道在 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 警告的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!