-
-
Notifications
You must be signed in to change notification settings - Fork 208
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Document proxy object 'const' not being constant in Rcpp FAQ #628
Comments
Proposed entry in the inaugural Section 5: Known Issues Title: Rcpp changed the (const) object I passed by value Text: \pkg{Rcpp} objects are wrappers around the underlying \R objects' \code{SEXP} , or S-expression. The \code{SEXP} is a pointer variable that holds the location of where the \R object data has been stored \citep[][Section 1.1]{R:Internals}. That is to say, the \code{SEXP} does \textit{not} hold the actual data of the \R object but merely a reference to where the data resides. When creating a new \pkg{Rcpp} object for an \R object to enter \proglang{C++}, this object will use the same \code{SEXP} that powers the original \R object if the types match otherwise a new \code{SEXP} must be created to be type safe. In essence, the underlying \code{SEXP} objects are passed by reference without explicit copies being made into \proglang{C++}. We refer to this arrangement as a \textit{proxy model}. As for the actual implementation, there are a few consequences of the proxy model. The foremost consequence within this paradigm is that pass by value is really a pass by reference. In essence, the distinction between the following two functions is only visual sugar: void implicit_ref(NumericVector X);
void explicit_ref(NumericVector& X); In particular, when one is passing by value what occurs is the instantiation of the new \pkg{Rcpp} object that uses the same \code{SEXP} for the \R object. As a result, the \pkg{Rcpp} object is ``linked'' to the original \R object. Thus, if an operation is performed on the \pkg{Rcpp} object, such as adding 1 to each element, the operation also updates the \R object. #include<Rcpp.h>
// [[Rcpp::export]]
void implicit_ref(Rcpp::NumericVector X){
X = X + 1.0;
}
// [[Rcpp::export]]
void explicit_ref(Rcpp::NumericVector& X){
X = X + 1.0;
}
/*** R
a <- 1.5:10.5
b <- 1.5:10.5
# Implicit
implicit_ref(a)
a
# Explicit test
explicit_ref(b)
b
*/ There are two exceptions to this rule. The first exception is that a deep copy of the object can be made by explicit use of \code{Rcpp:clone()}. In this case, the cloned object has no link to the original \R object. However, there is a time cost associated with this procedure as new memory must be allocated and the previous values must be copied over. The second exception, which was previously foreshadowed, is encountered when \pkg{Rcpp} and \R object types do not match. One frequent example of this case is when the \R object generated from \code{seq()} or \code{a:b} reports a class of \code{"integer"} while the \pkg{Rcpp} object is setup to receive the class of \code{"numeric"} as its object is set to \code{NumericVector} or \code{NumericMatrix}. In such cases, this would lead to a new \code{SEXP} object being created behind the scenes and, thus, there would \textit{not} be a link between the \pkg{Rcpp} object and \R object. #include<Rcpp.h>
// [[Rcpp::export]]
void num_vec_type(Rcpp::NumericVector X){
X = X + 1.0;
}
// [[Rcpp::export]]
void int_vec_type(Rcpp::IntegerVector X){
X = X + 1.0;
}
/*** R
a <- 1.5:10.5
b <- 1.5:10.5
# View the object type
class(a)
# Correct type
num_vec_type(a)
a
# Mismatch
int_vec_type(b)
b
*/ With this being said, there is one last area of contention with the proxy model: the keyword \code{const}. Similar to the pass by value versus pass by reference conundrum, the \code{const} declaration that indicates an object cannot be modified is just cosmetic because of the underlying R semantics and data structures. There is no ability to force the appropriate \proglang{C++} behavior that traditionally governs \code{const} declarations. In some cases, the compiler may provide warnings that a \code{const} object is being modified. However, it is best to not rely upon the \code{const} keyword. |
That's pretty good, thank you. |
Made some small edits within. |
See eg #627 for a very recent example. That should have gone to the FAQ ages ago.
The text was updated successfully, but these errors were encountered: