C中的R扩展:参考SEXP保护堆栈高度

C中的R扩展:参考SEXP保护堆栈高度,c,r,C,R,我正在使用.Call接口编写R扩展,并试图跟踪堆栈不平衡警告。如果我能够在代码中的不同点上查看堆栈高度,以隔离内部C函数,这些函数返回的SEXP PROTECT堆栈高度与调用它们时的高度不同,我会发现这非常有用 有办法做到这一点吗 是的,我意识到,如果我使用Rcpp,我就不必担心这些,但我在这里太深了,无法改变 一种不太理想的可能性是这样一种模式: int start, end; PROTECT_WITH_INDEX(R_NilValue, &start); UNPROTECT(1);

我正在使用
.Call
接口编写R扩展,并试图跟踪堆栈不平衡警告。如果我能够在代码中的不同点上查看堆栈高度,以隔离内部C函数,这些函数返回的SEXP PROTECT堆栈高度与调用它们时的高度不同,我会发现这非常有用

有办法做到这一点吗

是的,我意识到,如果我使用Rcpp,我就不必担心这些,但我在这里太深了,无法改变

一种不太理想的可能性是这样一种模式:

int start, end;
PROTECT_WITH_INDEX(R_NilValue, &start);
UNPROTECT(1);
call_to_suspect_fun();
PROTECT_WITH_INDEX(R_NilValue, &end);
UNPROTECT(1);
if(start != end) error("Stack imbalance right here!");

这看起来非常尴尬。我想转换成函数很容易,但如果没有更好的内置选项,我会感到惊讶。

堆栈顶部不是公共API的一部分,但可以使其可见

#include "Rinternals.h"

extern int R_PPStackTop;

SEXP stacktop()
{
    SEXP x;
    Rprintf("%d\n", R_PPStackTop);
    x = PROTECT(allocVector(INTSXP, 1));
    Rprintf("%d\n", R_PPStackTop);
    UNPROTECT(1);
    Rprintf("%d\n", R_PPStackTop);
    return Rf_ScalarInteger(R_PPStackTop);
}
导致

$ R CMD SHLIB stacktop.c 2&> /dev/null
$ R --vanilla -e "dyn.load('stacktop.so'); .Call('stacktop')"
> dyn.load('stacktop.so'); .Call('stacktop')
3
4
3
[1] 3

杰出的我不知道你能做到这一点(并且通常认为任何不在Rinternals的东西都是不允许的)。