This document provide brief instruction for calling C from R using Rcpp. This chapter from Advanced R provides a wonderful and comprehensive description of Rcpp. Many materials in this lecture are borrowed from there.

There are two old-fashion R-to-C interfaces: .C and .Call, for those I have some description here, and some comparisons here.

### Prerequisite

• Need to have a system supports C compiler (gcc, clang, etc). If you want to have C code within R package, supports for make, perl are necessary.
• Linux system has those by default.
• On Mac OS, a compiler system like Xcode needs to be installed.
• On Windows, needs to install a compiler system. The easiest is to install Rtools, which contains all necessary tools for this.
• Of course, you need to know how to program C.

### Inline C code with cppFunction

We demonstrate this using a very simple Hello world example. It just prints out a Hello world message. There’s no input/output.

library(Rcpp)
cppFunction( 'void hello() {
printf("Hello world"); }' )
hello()

A few notes:

• cppFunction takes source C code as character in R. So the whole chunk of C++ codes needs to be enclosed by single quotations marks.
• Running it the first time in the R session, the C code will be complied and load in as a shared library. That will take some time. The shared libraray resides in the memory. So the code will be recompiled in a new R session.
• This only works for small C code, not meant to be really useful.

### Standalone C code with sourceCpp

In most cases you want to write and save your C/C++ codes in a seperate file. Below is my hello function, which is saved in a seperate file hello.cpp.

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
void hello() {
printf("Hello world! \n");
}

The function can be compiled and load into R by

sourceCpp("hello.cpp")

Now the function can be accessed in R by hello().

A few notes:

• The first two lines are mandatory for each file to be sourceCpp’ed into R.
• The third line is required for each function that can be accessed in R.
• The cpp will be recompiled and loaded into R for every new R session. meaning that the results (usually .o and .so files) from compilation are not saved.

### Compile and load standalone Rcpp function

To recompile the C++ code for every new R session is not ideal. To compile it once and use forever, there are two options:

• Include the C++ code in an R pacakge (introduced later)
• Use the old fashion .C or .Call way to include C/C++ code. I have some descriptions here.

### With input and output

Now we will write a slightly more complicated function to compute the sum of a vector. Here is the C code named mySum.cpp. It takes a vector from R, computes and returns the sum.

#include <Rcpp.h>
using namespace Rcpp;

// [[Rcpp::export]]
double mySum(NumericVector x) {
int i;
double result=0.0;

for(i=0; i<x.size(); i++)
result = result + x[i];
return(result);
}

Now we can compile and run it in R

sourceCpp("mySum.cpp")
mySum(1:10)

A few notes:

• NumericVector is the data type defined in Rcpp (it’s not a standard C++ data type)
• The length of the vector can be accessed by size() function.
• The index in C starts from 0 (R starts from 1). Be careful.

### Working with Matrix in C++

The function below (myRowSum.cpp) computes the row-wise sums of a matrix.

#include <Rcpp.h>
using namespace Rcpp;
// [[Rcpp::export]]
NumericVector myRowSum( NumericMatrix x ) {
int nrow = x.nrow(), ncol = x.ncol();
int i, j;
double tmp;
NumericVector result(nrow);

for(i=0; i<nrow; i++) {
tmp = 0.0;
for(j=0; j<ncol; j++)
tmp = tmp + x(i,j);
result[i] = tmp;
}
return(result);
}

Now we can compile run the code in R

sourceCpp("myRowSum.cpp")
X = matrix(1:6, ncol=2)
myRowSum(X)

A few notes:

• R matrix passed into Rcpp as an object of NumericMatrix.
• The numbers of rows and columns can be accessed by nrow() and ncol() functions in C++.
• The (i,j)-th elements in the matrix can be accessed by x(i,j). Pay attention: it’s (), not [], different from accessing a NumericVector.

### Rcpp data types

Variables passed from R to C++ need to be declared with correct data types. Basic data types in C++ are:

• Scalar: int, double, bool, String
• Vector: IntegerVector, NumericVector, LogicalVector, CharacterVector
• Matrix: IntegerMatrix, NumericMatrix, LogicalMatrix, CharacterMatrix

For more complex data types and classes (list, data frame, function, etc.) please refer to the Rcpp manual.

### C++ code with R package

Now I want to create a package pkgwithRcpp with some C++ codes. Assume I have the cpp file (myRowSum.cpp) in current directory, I can do the following:

1. Run

Rcpp.package.skeleton("pkgwithRcpp", cpp_files="myRowSum.cpp",
example_code=FALSE, attributes=FALSE)

This creates the package skeleton. Note that

• Rcpp.package.skeleton is a function in Rcpp providing similar functionality of the standard package.skeleton function. But it addes additional lines in DESCRIPTION and NAMESPACE files to ensure the C++ codes can be accessed.
• After this step, a new directory pkgwithRcpp will appear in current directory with necessary files.
• Under pkgwithRcpp, there is a src subdirectory containing the C++ code.
• Under pkgwithRcpp, the R subdirectory is empty.
2. Run Rcpp::compileAttributes("pkgwithRcpp"). This step will scan the package and generate some necessary files. After this step, a new file RcppExports.R will appear in the R subdirectory, which defines the R interface function for the C function.

3. Now the package can be built and installed using typical procedure.

A few notes:

• The messages for compiling C++ will appear when the package is being installed.

• Anyone who needs to install this package from source need to have C++ compiler.

• To avoid that, one can build a (platform-dependent) binary package, which precompiles the C++ code so that user without a compiler can install. Do following to build binary package:

  R CMD INSTALL --build pkgwithRcpp
• If I need to have multiple C++ files in the package, I can copy all cpp files into the src directory. But after adding new cpp files, I need to rerun Rcpp::compileAttributes("pkgwithRcpp") to update the R wrapper function.

For more details, view vignette("Rcpp-package").

### Debug standalone C code

Here I will introduce how to debug a standalone C code. Debugging C code within an R package is slightly different, which will be introduced later.

Debugging function is platform-dependent.

• When the compiler is g++, the debugger is gdb
• When the compiler is clang++, the debugger is lldb.

As an example below, I debug myRowSum function. The typical steps are:

1. Run R within a GNU debugger.

• On linux, run R -d gdb.
• On newer versions of Mac OSX, run R -d lldb.
2. Once we are in the debugger, start R by doing run. Then we will be in the R console.

3. Debugging steps.

• Compile and load in the function sourceCpp("myRowSum.cpp").
• Press Control-C to switch back to lldb environment.
• Set a breakpoint, say, at line 11: myRowSum.cpp:11.
• After setting breakpoint, go back to R by typing continue in lldb. Now we come back to R.
• Run the following codes.
    X = matrix(1:6, ncol=2)
myRowSum(X)
• Once the breakpoint in myRowSum is hit, it will go to lldb environment. We can then do all sorts of debugging, such as run line by line, inspect the value of variables, etc.

For detailed commands for gdb and lldb, see https://lldb.llvm.org/use/map.html.

### Debug C code with R package

Debug C/C++ codes with an R package is a little troubler. Here is an excellent description: https://blog.davisvaughan.com/2019/04/05/debug-r-package-with-cpp/.

The first important thing is to make sure the C/C++ codes are compiled with a “debug-able” flag (usually a -g). This can be achieved by modifying the .R/Makevars files (Or you can run usethis::edit_r_makevars() in R) by adding a few lines like

CXXFLAGS = -g -O0
CFLAGS = -g -O0
CPPFLAGS = -g -O0

Make sure you change it back (from -O0 to -O2), or remove this file after debugging. Otherwise all future packages will be compiled with debug flag, which will make them slower.

The general steps of debuggin the C/C++ codes with an R package is:

1. Start R with with debugger R -d lldb
2. Run R in lldb
3. Load in library
4. Break back to lldb (Control-C), set breakpoint in C code.
5. Back to R by `continue’, call R function. Once the breakpoint is hit, it will go to lldb.