C中的R扩展:咨询SEXP PROTECT堆栈高度

Bro*_*ieG 5 c r

我正在使用.Call界面编写R扩展,我正在尝试追踪堆栈不平衡警告.如果我能够在代码中的各个点查询堆栈高度以隔离在调用它们的相同SEXP PROTECT堆栈高度时没有返回的内部C函数,我会发现它非常有用.

有没有办法做到这一点?

是的,我意识到如果我使用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!");
Run Code Online (Sandbox Code Playgroud)

这似乎超级尴尬.我想这很容易变成一个函数,但如果没有更好的内置选项,我会感到惊讶.

Mar*_*gan 5

堆栈的顶部不是公共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);
}
Run Code Online (Sandbox Code Playgroud)

导致

$ 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
Run Code Online (Sandbox Code Playgroud)