Rcpp:如果我施放 to/from SEXP,对象是否受到安全保护?

Rcpp: are objects safely PROTECTed if I cast to/from SEXP?

在 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;
}

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

您可以轻松验证,只需手动创建一次 SEXP 没有保护层 并且 R 会在 R CMD check [=24= 中告诉您] 崩溃。

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