Description
I've observed a difference in behavior between Rcpp::Language
and the lower-level Rf_lang*
functions when constructing function calls.
To my understanding, function calls in R are essentially pairlists (LANGSXP
) that hold SEXP
— that is, pointers to R objects. As such, if an argument is modified after the call is constructed, the change should be visible during evaluation, since the call stores only pointers, not copies.
However, calls created using Rcpp::Language
do not reflect such modifications. It appears that the arguments are deep-copied during the construction of the call. This behavior did not occur in Rcpp 1.0.13, but it does appear in Rcpp 1.0.14.
Here is a minimal reproducible example:
Rcpp::cppFunction("
void test_call(Function f) {
auto v = NumericVector::create(0.0, 1.0);
Rcpp::Language call_Rcpp(f, v);
Rcpp::Shield<SEXP> call_lang(Rf_lang2(f, v));
v[0] = 999.0;
Rcpp::Rcout << as<double>(Rcpp_fast_eval(call_Rcpp, R_GlobalEnv)) << std::endl;
Rcpp::Rcout << as<double>(Rcpp_fast_eval(call_lang, R_GlobalEnv)) << std::endl;
}
")
test_call(sum)
#> 1
#> 1000
I'm wondering whether this change in behavior was intentional, or if it might be an unintended consequence of recent updates?