04 - Read-only versus Writable R Objects

Read and write

In cpp4r, when you declare a variable, it is read-only by default as in cpp11 [@vaughan24]. This is different from Rcpp, where variables are read-write by default [@eddelbuettel11].

Following from the package created in the previous vignette, try to compile and run the following code by adding it to a new file src/04_square_coordinates.h:

[[cpp4r::register]]
integers square_coordinates_(integers x) {
  integers out = x;
  for (int i = 0; i < x.size(); ++i) {
    out[i] = x[i] * x[i];
  }
  return out;
}

devtools::load_all() and devtools::install() will fail with the following error:

error: lvalue required as left operand of assignment
  out[i] = x[i] * x[i];

This is because the argument x is a read-only object, you need to explicitly declare a writable variable:

[[cpp4r::register]]
integers square_coordinates(integers x) {
  writable::integers out = x;
  for (int i = 0; i < x.size(); ++i) {
    out[i] = x[i] * x[i];
  }
  return out;
}

Alternatively, you can declare the argument as writable:

[[cpp4r::register]]
integers square_coordinates_2(writable::integers x) {
  for (int i = 0; i < x.size(); ++i) {
    x[i] = x[i] * x[i];
  }
  return x;
}

Do not forget to include the new header file in main.cpp:

Document these functions with roxygen and compare their outputs after loading the updated package:

cpp4r::register()
devtools::document()
devtools::load_all()

Compare square_coordinates(1:3), square_coordinates(c(1, 2, 3)), and square_coordinates(c(1L, 2L, 3L)). Why do the outputs differ? Are integers and doubles interchangeable as double and int in C++ for reasonable cases?

References



Try the cpp4r package in your browser

Any scripts or data that you put into this service are public.

cpp4r documentation built on Sept. 23, 2026, 5:06 p.m.