2013-10-22 4 views
10

I今writing R extensions複数回でのガベージコレクションについてのビットを再読み込み、まだこれらの二つの用法の違いを理解していない。これまでのところPROTECTで割当てが正確に処理されるべきものは何ですか?

SEXP var; 
PROTECT(var = allocVector(STRSXP, 100)); 

SEXP var = PROTECT(allocVector(STRSXP, 100)); 

私はしました私のセッションが時々クラッシュするにつれて、最初のものとの運が悪かったです(しかし、実際のコードとイントロガイドの両方でその使用法がよく分かります)。誰かがこの2つの課題の違いを説明できますか?

編集:

いくつかの実験の後、私は私が上記の二つの間に違いはありませんし、私が見るの行動をクラッシュの違いは偶然のですが、からの確認をお願い申し上げますという結論に来ていると思いますもっと経験豊かな人。

+4

同等であるが、 'Rinterを読んでnals.h'は 'SEXP'はポインタ型で、マクロ' PROTECT'は単にライブラリ関数 'Rf_protect'の呼び出しに展開されます。一緒に言えば、これは、 'PROTECT'がスタック上の変数で賢明なことをしていないことを意味します。一時的なGCルートとして 'allocVector'から戻ってきた*オブジェクト*をマークすることしかできません。したがって、2つの構成は等価でなければなりません。 (代入文の値、 'var = ...'は 'var'に書き込まれた値です。) – zwol

答えて

7

これは厳密に同等です。これは、(https://svn.r-project.org/R/trunk/src/main/memory.cから)

SEXP protect(SEXP s) 
{ 
    if (R_PPStackTop >= R_PPStackSize) 
    R_signal_protect_error(); 
    R_PPStack[R_PPStackTop++] = CHK(s); 
    return s; 
} 

static R_INLINE SEXP CHK(SEXP x) 
{ 
    /* **** NULL check because of R_CurrentExpr */ 
    if (x != NULL && TYPEOF(x) == FREESXP) 
    error("unprotected object (%p) encountered (was %s)", 
      x, sexptype2char(OLDTYPE(x))); 
    return x; 
} 
#else 
#define CHK(x) x 
#endif 

とfrom.include/Rinternals.h PROTECTによって呼び出される関数です:

#define TYPEOF(x) ((x)->sxpinfo.type) 

あなたが見ることができるようになるように

、ポインタ引数は、そのまま返されます
var = PROTECT(p) 
PROTECT(var = p) 

は、私は確かに知っていないので、これが答えではない

関連する問題