【问题标题】:Rcpp: are objects safely PROTECTed if I cast to/from SEXP?Rcpp:如果我向/从 SEXP 投射,对象是否受到安全保护?
【发布时间】:2021-01-07 21:00:46
【问题描述】:

在 C 或 C++ 中创建 R 扩展时,在编译代码中创建的对象需要手动保护并且不受垃圾收集器的保护 - 例如:

SEXP some_func(SEXP inp)
{
    SEXP some_vec = PROTECT(Rf_allocVector(REALSXP, 100));
    // do something with 'some_vec' ...
    UNPROTECT(1);
    return some_vec;
}

Rcpp OTOH 提供了方便的类,可以自动处理 PROTECTUNPROTECT 调用,因此可以安全地执行以下操作:

Rcpp::NumericVector some_func(SEXP inp)
{
    Rcpp::NumericVector some_vec(100);
    // do something with 'some_vec' ...
    return some_vec;
}

现在,如果我将 Rcpp 对象转换为通用 SEXP,它们是否仍然是自动保护的?示例:

SEXP some_func(SEXP inp)
{
    SEXP some_vec = Rcpp::NumericVector(100);
    // do something with 'some_vec' ...
    return some_vec;
}

由于some_vec 被分配为专门的NumericVector,但随后又被转换为SEXP,它是否仍会自动进行PROTECT/UNPROTECT,还是我需要手动进行?

那么反过来投射呢?例如。这安全吗?

Rcpp::NumericVector some_func(SEXP inp)
{
    Rcpp::NumericVector some_vec = Rf_allocVector(REALSXP, 100);
    // do something with 'some_vec' ...
    return some_vec;
}

【问题讨论】:

  • 这是Rcpp 的众多令人敬畏的功能之一。它允许人们更多地关注实际问题。

标签: rcpp


【解决方案1】:

是的,因为 R 的唯一接口使用 SEXP .Call(SEXP ...)。因此,每个 Rcpp 对象都会自动进行转换(很多隐式转换,也可以通过Rcpp::wrap(...)),而保护就是其中的一部分。

您可以通过手动创建一次SEXP 轻松验证这一点没有保护层,R 会在R CMD check 和/或崩溃中告诉您。

由此您可以得出结论,Rcpp 对象受到了正确的保护,因为这不会发生在它们身上。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-08
    • 1970-01-01
    • 2019-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-15
    相关资源
    最近更新 更多