Compiler optimization
Motivation
Vaughan, Hester, and Francois (2024) already provides some details. Here I will expand on the differences between cpp11
and Rcpp
.
Read and write
In cpp11
, when a variable is declared, it is read-only by default. This is different from Rcpp
, where variables are read-write by default.
This code will not compile in cpp11
:
[[cpp11::register]] integers square_coordinates_(integers x) {
= x;
integers out for (int i = 0; i < x.size(); ++i) {
[i] = x[i] * x[i];
out}
return out;
}
The error message is:
code.cpp:515:10: error: lvalue required as left operand of assignment
515 | out[i] = x[i] * x[i];
To fix this, you need to explicitly declare the variable as writable:
[[cpp11::register]] integers square_coordinates_(integers x) {
::integers out = x;
writablefor (int i = 0; i < x.size(); ++i) {
[i] = x[i] * x[i];
out}
return out;
}
The arguments are also read-only by default in cpp11
, unless you declare them as writable, as in the following example:
[[cpp11::register]] integers square_coordinates2_(writable::integers x) {
for (int i = 0; i < x.size(); ++i) {
[i] = x[i] * x[i];
x}
return x;
}
External pointers
In cpp11
, you can use external_pointer
. In Rcpp
, you can use XPtr
to create external pointers. These have a quite different syntax, and cpp11
does not provide an attr
method for external pointers.
For example, the cpp11tesseract package defines:
typedef cpp11::external_pointer<tesseract::TessBaseAPI, tess_finalizer> TessPtr;
Then TessPtr
is called with:
(api);
TessPtr ptrreturn ptr;
As a result, the R equivalent that the OCR C++ function verifies that the engine is such that the following is true:
stopifnot(inherits(engine, "externalptr"))
The equivalent tesseract package, that uses Rcpp
, defines:
typedef Rcpp::XPtr<tesseract::TessBaseAPI, Rcpp::PreserveStorage, tess_finalizer, true> TessPtr;
Then TessPtr
is called with:
(api);
TessPtr ptr.attr("class") = Rcpp::CharacterVector::create("tesseract");
ptrreturn ptr;
Similarly, the Rcpp
version checks the engine with:
stopifnot(inherits(engine, "tesseract"))