0% found this document useful (0 votes)
60 views13 pages

RCPP FAQ: Dirk Eddelbuettel and Romain François

This document summarizes the Frequently Asked Questions about the Rcpp package. It begins by explaining how to get started with Rcpp, including what is needed like R and a compiler. It then covers questions about compiling and linking C++ code with Rcpp, providing examples of tasks like matrix algebra. The document also addresses support questions and known issues when using Rcpp.

Uploaded by

Rhamon Talles
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
60 views13 pages

RCPP FAQ: Dirk Eddelbuettel and Romain François

This document summarizes the Frequently Asked Questions about the Rcpp package. It begins by explaining how to get started with Rcpp, including what is needed like R and a compiler. It then covers questions about compiling and linking C++ code with Rcpp, providing examples of tasks like matrix algebra. The document also addresses support questions and known issues when using Rcpp.

Uploaded by

Rhamon Talles
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 13

Rcpp FAQ

Dirk Eddelbuettela and Romain Françoisb


a
http://dirk.eddelbuettel.com; b https://romain.rbind.io/

This version was compiled on July 20, 2019

This document attempts to answer the most Frequently Asked Questions 3.6 How do I write a plugin for inline and/or Rcpp
(FAQ) regarding the Rcpp (Eddelbuettel et al., 2019a; Eddelbuettel and Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . 7
François, 2011; Eddelbuettel, 2013) package. 3.7 How can I pass one additional flag to the compiler 7
3.8 How can I set matrix row and column names . . . . 8
Rcpp | FAQ | R | C++
3.9 Why can long long types not be cast correctly . . . . 8
3.10 What LaTeX packages do I need to typeset the vignettes 8
Contents 3.11 Why is there a limit of 20 on some constructors . . 8
3.12 Can I use default function parameters with Rcpp . 9
1 Getting started 1 3.13 Can I use C++11, C++14, C++17, . . . with Rcpp . 9
1.1 How do I get started . . . . . . . . . . . . . . . . . . . 1 3.14 How do I use it within (Python’s) Conda setup? . . 9
1.2 What do I need . . . . . . . . . . . . . . . . . . . . . . 2
1.3 What compiler can I use . . . . . . . . . . . . . . . . . 2 4 Support 9
1.4 What other packages are useful . . . . . . . . . . . . 2 4.1 Is the API documented . . . . . . . . . . . . . . . . . . 9
1.5 What licenses can I choose for my code . . . . . . . . 2 4.2 Does it really work . . . . . . . . . . . . . . . . . . . . 9
4.3 Where can I ask further questions . . . . . . . . . . . 9
2 Compiling and Linking 2
4.4 Where can I read old questions and answers . . . . 9
2.1 How do I use Rcpp in my package . . . . . . . . . . . 2
4.5 I like it. How can I help . . . . . . . . . . . . . . . . . 10
2.2 How do I quickly prototype my code . . . . . . . . . 2
2.2.1 Using inline . . . . . . . . . . . . . . . . . . . . 2 4.6 I don’t like it. How can I help . . . . . . . . . . . . . . 10
2.2.2 Using Rcpp Attributes . . . . . . . . . . . . . . 3 4.7 Can I have commercial support for Rcpp . . . . . . . 10
2.3 How do I convert my prototyped code to a package 3 4.8 I want to learn quickly. Do you provide training
2.4 How do I quickly prototype my code in a package . 3 courses . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
2.5 But I want to compile my code with R CMD SHLIB 3 4.9 Where is the code repository . . . . . . . . . . . . . . 10
2.6 But R CMD SHLIB still does not work . . . . . . . . . 4
5 Known Issues 10
2.7 What about LinkingTo . . . . . . . . . . . . . . . . . 4
2.8 Does Rcpp work on windows . . . . . . . . . . . . . . 4 5.1 Rcpp changed the (const) object I passed by value . 10
2.9 Can I use Rcpp with Visual Studio . . . . . . . . . . . 4 5.2 Issues with implicit conversion from an Rcpp object
2.10 I am having problems building Rcpp on macOS, any to a scalar or other Rcpp object . . . . . . . . . . . . 11
help . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 5.3 Using operator= with a scalar replaced the object
2.10.1 Lack of a Compiler . . . . . . . . . . . . . . . . 4 instead of filling element-wise . . . . . . . . . . . . . 11
2.10.2 Differing macOS R Versions Leading to Bi- 5.4 Long Vector support on Windows . . . . . . . . . . . 12
nary Failures . . . . . . . . . . . . . . . . . . . 4 5.5 Sorting with STL on a CharacterVector produces
2.10.3 OpenMP Support . . . . . . . . . . . . . . . . . 4 problematic results . . . . . . . . . . . . . . . . . . . . 12
2.10.4 Additional Information and Help . . . . . . . 4 5.6 Lexicographic order of string sorting differs due to
2.11 Does Rcpp work on solaris/suncc . . . . . . . . . . . 4 capitalization . . . . . . . . . . . . . . . . . . . . . . . . 13
2.12 Does Rcpp work with Revolution R . . . . . . . . . . 4 5.7 Package building fails with ‘symbols not found’ . . . 13
2.13 Is it related to Rho (formerly CXXR) . . . . . . . . . 4
2.14 How do I quickly prototype my code using Attributes 5 1. Getting started
2.15 What about the new ‘no-linking’ feature . . . . . . . 5
2.16 I am having problems building RcppArmadillo on 1.1. How do I get started. If you have Rcpp installed, please exe-
macOS, any help . . . . . . . . . . . . . . . . . . . . . 5 cute the following command in R to access the introductory vignette
(which is a variant of the Eddelbuettel and François (2011) and
3 Examples 5 Eddelbuettel and Balamuta (2017, 2018) papers) for a detailed in-
3.1 Can I use templates with Rcpp . . . . . . . . . . . . . 5 troduction, ideally followed by at least the Rcpp Attributes (Allaire
3.1.1 Using inline with Templated Code . . . . . . 5 et al., 2018) vignette:
3.1.2 Using Rcpp Attributes with Templated Code 5
3.2 Can I do matrix algebra with Rcpp . . . . . . . . . . 5 vignette("Rcpp-jss-2011")
3.2.1 Using inline with RcppArmadillo . . . . . . . 6 vignette("Rcpp-introduction")
3.2.2 Using Rcpp Attributes with RcppArmadillo . 6 vignette("Rcpp-attributes")
3.3 Can I use code from the Rmath header and library
with Rcpp . . . . . . . . . . . . . . . . . . . . . . . . . . 6 If you do not have Rcpp installed, these documents should also
3.4 Can I use NA and Inf with Rcpp . . . . . . . . . . . . 7 be available whereever you found this document, i.e., on every
3.5 Can I easily multiply matrices . . . . . . . . . . . . . 7 mirror site of CRAN.

https://cran.r-project.org/package=Rcpp Rcpp Vignette | July 20, 2019 | 1–13


1.2. What do I need. Obviously, R must be installed. Rcpp provides by the Rcpp Attributes (see FAQ 2.2.2 and FAQ 2.14) feature
a C++ API as an extension to the R system. As such, it is bound by provided by Rcpp;
the choices made by R and is also influenced by how R is configured.
In general, the standard environment for building a CRAN pack- RUnit is used for unit testing; the package is recommended and
age from source (particularly when it contains C or C++ code) is will be needed to re-run some of our tests but it is not strictly
required. This means one needs: required during use of Rcpp;

• a development environment with a suitable compiler (see rbenchmark to run simple timing comparisons and benchmarks;
below), header files and required libraries; it is also recommended but not required.
• R should be built in a way that permits linking and pos-
microbenchmark is an alternative for benchmarking.
sibly embedding of R; this is typically ensured by the
--enable-shared-lib option; devtools can help the process of building, compiling and testing
• standard development tools such as make etc. a package but it too is entirely optional.
Also see the RStudio documentation on pre-requisites for R
1.5. What licenses can I choose for my code. The Rcpp package
package development.
is licensed under the terms of the GNU GPL 2 or later, just like R
itself. A key goal of the Rcpp package is to make extending R more
1.3. What compiler can I use. On almost all platforms, the GNU
seamless. But by linking your code against R (as well as Rcpp),
Compiler Collection (or gcc, which is also the name of its C lan-
the combination is bound by the GPL as well. This is very clearly
guage compiler) has to be used along with the corresponding g++
stated at the FSF website:
compiler for the C++ language. A minimal suitable version is a final
4.2.* release; earlier 4.2.* were lacking some C++ features (and Linking a GPL covered work statically or dynamically
even 4.2.1, still used on OS X as the last gcc release), has issues). with other modules is making a combined work based
Generally speaking, the default compilers on all the common on the GPL covered work. Thus, the terms and condi-
platforms are suitable. tions of the GNU General Public License cover the whole
Specific per-platform notes: combination.
Windows users need the Rtools package from the site maintained So you are free to license your work under whichever terms
by Duncan Murdoch which contains all the required tools in you find suitable (provided they are GPL-compatible, see the FSF
a single package; complete instructions specific to Windows site for details). However, the combined work will remain under
are in the ‘R Administration’ manual (R Core Team, 2018a, the terms and conditions of the GNU General Public License. This
Appendix D). As of August 2014, it still installs the gcc/g++ restriction comes from both R which is GPL-licensed as well as from
4.6.* compiler which limits the ability to use modern C++ Rcpp and whichever other GPL-licensed components you may be
standards so only s-std=c++0x is supported. R 3.1.0 and linking against.
above detect this and set appropriate flags.

OS X users, as noted in the ‘R Administration’ manual (R Core 2. Compiling and Linking


Team, 2018a, Appendix C.4), need to install the Apple Devel- 2.1. How do I use Rcpp in my package. Rcpp has been specifically
oper Tools (e.g., Xcode (OS X ≤ 10.8) or Xcode Command Line designed to be used by other packages. Making a package that uses
Tools (OS X ≥ 10.9) (as well as gfortran if R or Fortran-using Rcpp depends on the same mechanics that are involved in making
packages are to be built); also see FAQ 2.10 and FAQ 2.16 any R package that use compiled code — so reading the Writing R
below. Depending on whether on OS X release before or af- Extensions manual (R Core Team, 2018c) is a required first step.
ter Mavericks is used, different additional installation may Further steps, specific to Rcpp, are described in a separate
be needed. Consult the r-sig-mac list (and its archives) for vignette.
(current) details.
vignette("Rcpp-package")
Linux user need to install the standard developement packages.
Some distributions provide helper packages which pull in all
the required packages; the r-base-dev package on Debian 2.2. How do I quickly prototype my code. There are two toolchains
and Ubuntu is an example. which can help with this:

The clang and clang++ compilers from the LLVM project can • The older one is provided by the inline package and described
also be used. On Linux, they are inter-operable with gcc et al. On in Section~2.2.1.
OS X, they are unfortunately not ABI compatible. The clang++ • Starting with Rcpp 0.10.0, the Rcpp Attributes feature (de-
compiler is interesting as it emits much more comprehensible error scribed in Section~2.2.2) offered an even easier alternative
messages than g++ (though g++ 4.8 and 4.9 have caught up). via the function evalCpp, cppFunction and sourceCpp.
The Intel icc family has also been used successfully as its output
files can also be combined with those from gcc. The next two subsections show an example each.

2.2.1. Using inline. The inline package (Sklyar et al., 2018) provides
1.4. What other packages are useful. Additional packages that we
the functions cfunction and cxxfunction. Below is a simple
have found useful are:
function that uses accumulate from the (C++) Standard Template
inline which is invaluable for direct compilation, linking and load- Library to sum the elements of a numeric vector.
ing of short code snippets—but now effectively superseded

2 | https://cran.r-project.org/package=Rcpp Eddelbuettel and François


fx <- cxxfunction(signature(x = "numeric"), 2.4. How do I quickly prototype my code in a package. The sim-
’NumericVector xx(x); plest way may be to work directly with a package. Changes to both
return wrap( the R and C++ code can be compiled and tested from the command
std::accumulate(xx.begin(), line via:
xx.end(), $ R CMD INSTALL mypkg && \
0.0) Rscript --default-packages=mypkg -e \
);’, ’someFunctionToTickle(3.14)’
plugin = "Rcpp")
res <- fx(seq(1, 10, by=0.5)) This first installs the packages, and then uses the command-line
res tool Rscript (which ships with R) to load the package, and execute
# [1] 104.5 the R expression following the -e switch. Such an expression can
contain multiple statements separated by semicolons. Rscript is
One might want to use code that lives in a C++ file instead of available on all three core operating systems.
writing the code in a character string in R. This is easily achieved On Linux, one can also use r from the littler package by
by using readLines: Horner and Eddelbuettel which is an alternative front end to R
designed for both #! (hashbang) scripting and command-line use.
fx <- cxxfunction(signature(), It has slightly faster start-up times than Rscript; and both give a
paste(readLines("myfile.cpp"), guaranteed clean slate as a new session is created.
collapse="\n"), The example then becomes
plugin = "Rcpp") $ R CMD INSTALL mypkg && \
r -l mypkg -e ’someFunctionToTickle(3.14)’
The verbose argument of cxxfunction is very useful as it
shows how inline runs the show. The -l option calls ‘suppressMessages(library(mypkg))’ before
executing the R expression. Several packages can be listed, sepa-
2.2.2. Using Rcpp Attributes. Rcpp Attributes (Allaire et al., 2018), rated by a comma.
and also discussed in FAQ 2.14 below, permits an even easier route More choice are provide by the devtools package, and by using
to integrating R and C++. It provides three key functions. First, RStudio. See the respective documentation for details.
evalCpp provide a means to evaluate simple C++ expression which
2.5. But I want to compile my code with R CMD SHLIB. The rec-
is often useful for small tests, or to simply check if the toolchain
is set up correctly. Second, cppFunction can be used to create ommended way is to create a package and follow FAQ 2.1. The
C++ functions for R use on the fly. Third, Rcpp::sourceCpp can alternate recommendation is to use inline and follow FAQ 2.2.1
integrate entire files in order to define multiple functions. because it takes care of all the details.
However, some people have shown that they prefer not to fol-
The example above can now be rewritten as:
low recommended guidelines and compile their code using the
traditional R CMD SHLIB. To do so, we need to help SHLIB and
cppFunction(’double accu(NumericVector x) {
let it know about the header files that Rcpp provides and the C++
return(
library the code must link against.
std::accumulate(x.begin(), x.end(), 0.0)
On the Linux command-line, you can do the following:
);
}’) $ # if Rcpp older than 0.11.0
res <- accu(seq(1, 10, by=0.5)) $ export PKG_LIBS=‘Rscript -e "Rcpp:::LdFlags()"‘
res $ export PKG_CXXFLAGS=\
# [1] 104.5 ‘Rscript -e "Rcpp:::CxxFlags()"‘
$ R CMD SHLIB myfile.cpp
The cppFunction parses the supplied text, extracts the desired
function names, creates the required scaffolding, compiles, links which first defines and exports two relevant environment vari-
and loads the supplied code and makes it available under the ables which R CMD SHLIB then relies on. On other operating sys-
selected identifier. tems, appropriate settings may have to be used to define the envi-
ronment variables.
Similarly, sourceCpp can read in a file and compile, link and
This approach corresponds to the very earliest ways of building
load the code therein.
programs and can still be found in some deprecated documents
(as e.g. some of Dirk’s older ‘Intro to HPC with R’ tutorial slides).
2.3. How do I convert my prototyped code to a package. Since re- It is still not recommended as there are tools and automation
lease 0.3.5 of inline, one can combine FAQ 2.2.1 and FAQ 2.1. See mechanisms that can do the work for you.
help("package.skeleton-methods") once inline is loaded and Rcpp versions 0.11.0 or later can do with the definition of
use the skeleton-generating functionality to transform a prototyped PKG_LIBS as a user-facing library is no longer needed (and hence
function into the minimal structure of a package. After that you no longer shipped with the package). One still needs to set
can proceed with working on the package in the spirit of FAQ 2.1. PKG_CXXFLAGS to tell R where the Rcpp headers files are located.
Rcpp Attributes (Allaire et al., 2018) also offers a means to Once R CMD SHLIB has created the dyanmically-loadable file
convert functions written using Rcpp Attributes into a function via (with extension .so on Linux, .dylib on OS X or .dll on Win-
the compileAttributes function; see the vignette for details. dows), it can be loaded in an R session via dyn.load, and the

Eddelbuettel and François Rcpp Vignette | July 20, 2019 | 3


function can be executed via .Call. Needless to say, we strongly binaries to collaborators if they are working on older operating
recommend using a package, or at least Rcpp Attributes as either ap- systems as the R binaries for these versions will not be able to mix.
proach takes care of a lot of these tedious and error-prone manual In such cases, it is better to provide collaborators with the package
steps. source and allow them to build the package locally.

2.6. But R CMD SHLIB still does not work. We have had reports 2.10.3. OpenMP Support. By default, the macOS operating environ-
in the past where build failures occurred when users had non- ment lacks the ability to parallelize sections of code using the
standard code in their ~/.Rprofile or Rprofile.site (or equiv- [OpenMP](http://openmp.org/wp/) standard. Within R 3.4.*, the de-
alent) files. fault developer environment was changed to allow for OpenMP to
If such code emits text on stdout, the frequent and implicit be used on macOS by using a non-default toolchain provided by
invocation of Rscript -e "..." (as in FAQ 2.5 above) to retrieve R Core Team maintainers for macOS. Having said this, it is still
settings directly from Rcpp will fail. important to protect any reference to OpenMP as some users may
You may need to uncomment such non-standard code, or protect not yet have the ability to use OpenMP.
it by wrapping it inside if (interactive()), or possibly try to To setup the appropriate protection for using OpenMP, the pro-
use Rscript --vanilla instead of plain Rscript. cess is two-fold. First, protect the inclusion of headers with:

#ifdef _OPENMP
2.7. What about LinkingTo. R has only limited support for cross-
#include <omp.h>
package linkage.
#endif
We now employ the LinkingTo field of the DESCRIPTION file
of packages using Rcpp. But this only helps in having R compute
the location of the header files for us. Second, when parallelizing portions of code use:
The actual library location and argument still needs to be pro-
#ifdef _OPENMP
vided by the user. How to do so has been shown above, and we
// multithreaded OpenMP version of code
recommned you use either FAQ 2.1 or FAQ 2.2.1 both which use
#else
the Rcpp function Rcpp:::LdFlags().
// single-threaded version of code
If and when LinkingTo changes and lives up to its name, we
#endif
will be sure to adapt Rcpp as well.
An important change arrive with Rcpp release 0.11.0 and con-
cern the automatic registration of functions; see Section~2.15 Under this approach, the code will be safely parallelized when
below. support exists for OpenMP on Windows, macOS, and Linux.

2.10.4. Additional Information and Help. Below


are additional re-
2.8. Does Rcpp work on windows. Yes of course. See the Windows
binaries provided by CRAN. sources that provide information regarding compiling Rcpp code
on macOS.
2.9. Can I use Rcpp with Visual Studio. Not a chance.
1. A helpful post was provided by Brian Ripley regarding the
And that is not because we are meanies but because R and Visual
use of compiling R code with macOS in April 2014 on the
Studio simply do not get along. As Rcpp is all about extending R
r-sig-mac list, which is generally recommended for OS X-
with C++ interfaces, we are bound by the available toolchain. And
specific questions and further consultation.
R simply does not compile with Visual Studio. Go complain to its
2. Another helpful write-up for installation / compilation on OS
vendor if you are still upset.
X Mavericks is provided by the BioConductor project.
3. Lastly, another resource that exists for installation / com-
2.10. I am having problems building Rcpp on macOS, any help.
pilation help is provided at http://thecoatlessprofessor.com/
There are three known issues regarding Rcpp build problems on
programming/r-compiler-tools-for-rcpp-on-os-x/.
macOS. If you are building packages with RcppArmadillo, there is
yet another issue that is addressed separately in FAQ 2.16 below. Note: If you are running into trouble compiling code with
RcppArmadillo, please also see FAQ 2.16 listed below.
2.10.1. Lack of a Compiler. By
default, macOS does not ship with an
active compiler. Depending on the R version being used, there
2.11. Does Rcpp work on solaris/suncc. Yes, it generally does. But
are different development environment setup procedures. For the
as we do not have access to such systems, some issues persist on
current R version, we recommend observing the official procedure
the CRAN test systems.
used in Section 6.3.2 macOS and Section C.3 macOS of the R
Installation and Administration manual.
2.12. Does Rcpp work with Revolution R. We have not tested it yet.
2.10.2. Differing macOS R Versions Leading to Binary Failures. There are Rcpp might need a few tweaks to work with the compilers used by
currently three distinct versions of R for macOS. The first version Revolution R (if those differ from the defaults).
is a legacy version meant for macOS 10.6 (Snow Leopard) - 10.8
(Mountain Lion). The second version is for more recent system 2.13. Is it related to Rho (formerly CXXR). Rho, previously known
macOS 10.9 (Mavericks) and 10.10 (Yosemite). Finally, the third as CXXR, is an ambitious project that aims to totally refactor the R
and most up-to-date version supports macOS 10.11 (El Capitan), interpreter in C++. There are a few similaritites with Rcpp but the
10.12 (Sierra), and 10.13 (High Sierra). The distinction comes as a projects are unrelated.
result of a change in the compilers shipped with the operating sys- Rho / CXXR and Rcpp both want R to make more use of C++
tem as highlighted previously. As a result, avoid sending package but they do it in very different ways.

4 | https://cran.r-project.org/package=Rcpp Eddelbuettel and François


2.14. How do I quickly prototype my code using Attributes. Rcpp inc <- ’template <typename T>
version 0.10.0 and later offer a new feature ‘Rcpp Attributes’ which class square :
is described in detail in its own vignette (Allaire et al., 2018). In public std::unary_function<T,T> {
short, it offers functions evalCpp, cppFunction and sourceCpp public:
which extend the functionality of the cxxfunction function. T operator()( T t) const {
return t*t;
2.15. What about the new ‘no-linking’ feature. Starting with Rcpp }
0.11.0, functionality provided by Rcpp and used by packages };
built with Rcpp accessed via the registration facility offered by ’
R (and which is used by lme4 and Matrix, as well as by xts and
zoo). This requires no effort from the user / programmer, and src <- ’
even frees us from explicit linking instruction. In most cases, the double x = Rcpp::as<double>(xs);
files src/Makevars and src/Makevars.win can now be removed. int i = Rcpp::as<int>(is);
Exceptions are the use of RcppArmadillo (which needs an en- square<double> sqdbl;
try PKG_LIBS=$(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)) and square<int> sqint;
packages linking to external libraries they use. return Rcpp::DataFrame::create(
But for most packages using Rcpp, only two things are required: Rcpp::Named("x", sqdbl(x)),
Rcpp::Named("i", sqint(i)));
• an entry in DESCRIPTION such as Imports: Rcpp (which

may be versioned as in Imports: Rcpp (>= 0.11.0)), and
fun <- cxxfunction(signature(xs="numeric",
• an entry in NAMESPACE to ensure Rcpp is correctly instantiated,
is="integer"),
for example importFrom(Rcpp, evalCpp).
body=src, include=inc,
The name of the symbol does not really matter; once one symbol plugin="Rcpp")
is imported all symbols should be available.
fun(2.2, 3L)
2.16. I am having problems building RcppArmadillo on macOS, # x i
any help. Odds are your build failures are due to the absence of # 1 4.84 9
gfortran and its associated libraries. The errors that you may
receive are related to either -lgfortran or -lquadmath. 3.1.2. Using Rcpp Attributes with Templated Code. We can also use
To rectify the root of these errors, there are two options available. ‘Rcpp Attributes’ (Allaire et al., 2018)—as described in FAQ 2.2.2
The first option is to download and use a fixed set of gfortran and FAQ 2.14 above. Simply place the following code into a file
binaries that are used to compile R for macOS (e.g. given by the and use sourceCpp on it. It will even run the R part at the end.
maintainers of the macOS build). The second option is to either use
pre-existing gfortran binaries on your machine or download the #include <Rcpp.h>
latest. These options are described in-depth in Section C.3 macOS
of the R Installation and Administration manual. Please consult this template <typename T> class square :
manual for up-to-date information regarding gfortran binaries on public std::unary_function<T,T> {
macOS. We have also documented other common macOS compile public:
issues in Section FAQ 2.10. T operator()( T t) const {
return t*t ;
}
3. Examples
};
The following questions were asked on the Rcpp-devel mailing
list, which is our preferred place to ask questions as it guarantees // [[Rcpp::export]]
exposure to a number of advanced Rcpp users. The StackOverflow Rcpp::DataFrame fun(double x, int i) {
tag for rcpp is an alternative; that site is also easily searchable. square<double> sqdbl;
Several dozen fully documented examples are provided at the square<int> sqint;
Rcpp Gallery – which is also open for new contributions. return Rcpp::DataFrame::create(
Rcpp::Named("x", sqdbl(x)),
3.1. Can I use templates with Rcpp. Rcpp::Named("i", sqint(i)));
}
I’m curious whether one can provide a class definition
inline in an R script and then initialize an instance of the
/*** R
class and call a method on the class, all inline in R.
fun(2.2, 3L)
This question was initially about using templates with inline, */
and we show that (older) answer first. It is also easy with Rcpp
Attributes which is what we show below. 3.2. Can I do matrix algebra with Rcpp.
3.1.1. Using inline with Templated Code. Most
certainly, consider this Rcpp allows element-wise operations on vector and ma-
simple example of a templated class which squares its argument: trices through operator overloading and STL interface,
but what if I want to multiply a matrix by a vector, etc
...

Eddelbuettel and François Rcpp Vignette | July 20, 2019 | 5


Currently, Rcpp does not provide binary operators to allow oper- // [[Rcpp::export]]
ations involving entire objects. Adding operators to Rcpp would double fx(arma::colvec x, arma::mat Y,
be a major project (if done right) involving advanced techniques arma::colvec z) {
such as expression templates. We currently do not plan to go in // calculate the result
this direction, but we would welcome external help. Please send double result = arma::as_scalar(
us a design document. arma::trans(x) * arma::inv(Y) * z
However, we have developed the RcppArmadillo package (Ed- );
delbuettel et al., 2019b; Eddelbuettel and Sanderson, 2014) that return result;
provides a bridge between Rcpp and Armadillo (Sanderson, 2010). }
Armadillo supports binary operators on its types in a way that takes
full advantage of expression templates to remove temporaries and /*** R
allow chaining of operations. That is a mouthful of words mean- fx(1:4, diag(4), 1:4)
ing that it makes the code go faster by using fiendishly clever */
ways available via the so-called template meta programming, an
advanced C++ technique. Also, the RcppEigen package (Bates Here, the additional Rcpp::depends(RcppArmadillo) en-
and Eddelbuettel, 2013) provides an alternative using the Eigen sures that code can be compiled against the RcppArmadillo header,
template library. and that the correct libraries are linked to the function built from
the supplied code example.
3.2.1. Using inline with RcppArmadillo. The
following example is Note how we do not have to concern ourselves with conversion;
adapted from the examples available at the project page of Ar- R object automatically become (Rcpp)Armadillo objects and we
madillo. It calculates x 0 × Y −1 × z can focus on the single computing a (scalar) result.
lines = ’// copy the data to armadillo structures
3.3. Can I use code from the Rmath header and library with Rcpp.
arma::colvec x = Rcpp::as<arma::colvec> (x_);
arma::mat Y = Rcpp::as<arma::mat>(Y_) ; Can I call functions defined in the Rmath header file and
arma::colvec z = Rcpp::as<arma::colvec>(z_) ; the standalone math library for R–as for example the
random number generators?
// calculate the result Yes, of course. This math library exports a subset of R, but Rcpp
double result = arma::as_scalar( has access to much more. Here is another simple example. Note
arma::trans(x) * arma::inv(Y) * z how we have to use and instance of the RNGScope class to set and
); re-set the random-number generator. This also illustrates Rcpp
sugar as we are using a vectorised call to rnorm. Moreover, because
// return it to R the RNG is reset, the two calls result in the same random draws. If
return Rcpp::wrap( result );’ we wanted to control the draws, we could explicitly set the seed
after the RNGScope object has been instantiated.
writeLines(a, file = "myfile.cpp")
fx <- cxxfunction(signature(),
If stored in a file myfile.cpp, we can use it via inline: ’RNGScope();
return rnorm(5, 0, 100);’,
fx <- cxxfunction(signature(x_="numeric", plugin="Rcpp")
Y_="matrix", set.seed(42)
z_="numeric" ), fx()
paste(readLines("myfile.cpp"), # [1] 137.096 -56.470 36.313 63.286 40.427
collapse="\n"), fx()
plugin="RcppArmadillo" ) # [1] 137.096 -56.470 36.313 63.286 40.427
fx(1:4, diag(4), 1:4)
Newer versions of Rcpp also provide the actual Rmath function
The focus is on the code arma::trans(x) * arma::inv(Y)
in the R namespace, i.e. as R::rnorm(m,s) to obtain a scalar
* z, which performs the same operation as the R code t(x) %*%
random variable distributed as N (m, s).
solve(Y) %*% z, although Armadillo turns it into only one oper-
Using Rcpp Attributes, this can be as simple as
ation, which makes it quite fast. Armadillo benchmarks against
other C++ matrix algebra libraries are provided on the Armadillo cppFunction(’Rcpp::NumericVector ff(int n) {
website. return rnorm(n, 0, 100); }’)
It should be noted that code below depends on the version set.seed(42)
0.3.5 of inline and the version 0.2.2 of RcppArmadillo. ff(5)
# [1] 137.096 -56.470 36.313 63.286 40.427
3.2.2. Using Rcpp Attributes with RcppArmadillo. We can also write the
ff(5)
same example for use with Rcpp Attributes:
# [1] -10.6125 151.1522 -9.4659 201.8424 -6.2714
#include <RcppArmadillo.h> set.seed(42)
rnorm(5, 0, 100)
// [[Rcpp::depends(RcppArmadillo)]] # [1] 137.096 -56.470 36.313 63.286 40.427
rnorm(5, 0, 100)

6 | https://cran.r-project.org/package=Rcpp Eddelbuettel and François


# [1] -10.6125 151.1522 -9.4659 201.8424 -6.2714
#include <RcppArmadillo.h>
This illustrates the Rcpp Attributes adds the required RNGScope
object for us. It also shows how setting the seed from R affects // [[Rcpp::depends(RcppArmadillo)]]
draws done via C++ as well as R, and that identical random number
draws are obtained. // [[Rcpp::export]]
arma::mat mult(arma::mat A, arma::mat B) {
3.4. Can I use NA and Inf with Rcpp. return A*B;
}
R knows about NA and Inf. How do I use them from
C++? /*** R
Yes, see the following example: A <- matrix(1:9, 3, 3)
B <- matrix(9:1, 3, 3)
src <- ’Rcpp::NumericVector v(4); mult(A,B)
v[0] = R_NegInf; // -Inf */
v[1] = NA_REAL; // NA
v[2] = R_PosInf; // Inf which can be built, and run, from R via a simple sourceCpp
v[3] = 42; // c.f. Hitchhiker Guide call—and will also run the small R example at the end.
return Rcpp::wrap(v);’
fun <- cxxfunction(signature(), src, plugin="Rcpp") 3.6. How do I write a plugin for inline and/or Rcpp Attributes.
fun()
# [1] -Inf NA Inf 42 How can I create my own plugin for use by the inline
package?
Similarly, for Rcpp Attributes: Here is an example which shows how to it using GSL libraries
as an example. This is merely for demonstration, it is also not
#include <Rcpp.h>
perfectly general as we do not detect locations first—but it serves
as an example:
// [[Rcpp::export]]
Rcpp::NumericVector fun(void) { # simple example of seeding RNG and
Rcpp::NumericVector v(4); # drawing one random number
v[0] = R_NegInf; // -Inf gslrng <- ’
v[1] = NA_REAL; // NA int seed = Rcpp::as<int>(par) ;
v[2] = R_PosInf; // Inf gsl_rng_env_setup();
v[3] = 42; // c.f. Hitchhiker Guide gsl_rng *r = gsl_rng_alloc (gsl_rng_default);
return v; gsl_rng_set (r, (unsigned long) seed);
} double v = gsl_rng_get (r);
gsl_rng_free(r);
3.5. Can I easily multiply matrices. return Rcpp::wrap(v);’

Can I multiply matrices easily? plug <- Rcpp::Rcpp.plugin.maker(


include.before = "#include <gsl/gsl_rng.h>",
Yes, via the RcppArmadillo package which builds upon Rcpp and
libs = paste(
the wonderful Armadillo library described above in FAQ 3.2:
"-L/usr/local/lib/R/site-library/Rcpp/lib -lRcpp",
txt <- ’arma::mat Am = Rcpp::as< arma::mat >(A); "-Wl,-rpath,/usr/local/lib/R/site-library/Rcpp/lib",
arma::mat Bm = Rcpp::as< arma::mat >(B); "-L/usr/lib -lgsl -lgslcblas -lm")
return Rcpp::wrap( Am * Bm );’ )
mmult <- cxxfunction(signature(A="numeric", registerPlugin("gslDemo", plug )
B="numeric"), fun <- cxxfunction(signature(par="numeric"),
body=txt, gslrng, plugin="gslDemo")
plugin="RcppArmadillo") fun(0)
A <- matrix(1:9, 3, 3)
B <- matrix(9:1, 3, 3) Here the Rcpp function Rcpp.plugin.maker is used to create
C <- mmult(A, B) a plugin ‘plug’ which is then registered, and subsequently used by
C inline.
The same plugins can be used by Rcpp Attributes as well.
Armadillo supports a full range of common linear algebra oper-
ations. 3.7. How can I pass one additional flag to the compiler.
The RcppEigen package provides an alternative using the Eigen
How can I pass another flag to the g++ compiler without
template library.
writing a new plugin?
Rcpp Attributes, once again, makes this even easier:
The quickest way is to modify the return value from an ex-
isting plugin. Here we use the default one from Rcpp itself in

Eddelbuettel and François Rcpp Vignette | July 20, 2019 | 7


order to pass the new flag -std=c++0x. As it does not set the problems. But there are corner cases. The following example,
PKG_CXXFLAGS variable, we simply assign this. For other plugins, contributed by a user, shows that we cannot reliably cast long
one may need to append to the existing values instead. types (on a 64-bit machines).

myplugin <- getPlugin("Rcpp") BigInts <- cxxfunction(signature(),


myplugin$env$PKG_CXXFLAGS <- "-std=c++11" ’std::vector<long> bigints;
f <- cxxfunction(signature(), bigints.push_back(12345678901234567LL);
settings = myplugin, body = ’ bigints.push_back(12345678901234568LL);
// fails without -std=c++0x Rprintf("Difference of %ld\\n",
std::vector<double> x = { 1.0, 2.0, 3.0 }; 12345678901234568LL - 12345678901234567LL);
return Rcpp::wrap(x); return wrap(bigints);’,
’) plugin="Rcpp", includes="#include <vector>")
f()
retval <- BigInts()
For Rcpp Attributes, the attributes Rcpp::plugin() can be
used. Currently supported plugins are for C++11 as well as for # Unique 64-bit integers were cast to identical
OpenMP. # lower precision numerics behind my back with
# no warnings or errors whatsoever. Error.
3.8. How can I set matrix row and column names.
stopifnot(length(unique(retval)) == 2)
Ok, I can create a matrix, but how do I set its row and
columns names?
While the difference of one is evident at the C++ level, it is no
Pretty much the same way as in R itself: We define a list with longer present once cast to R. The 64-bit integer values get cast
two character vectors, one each for row and column names, and to a floating point types with a 53-bit mantissa. We do not have
assign this to the dimnames attribute: a good suggestion or fix for casting 64-bit integer values: 32-bit
integer values fit into integer types, up to 53 bit precision fits
src <- ’ into numeric and beyond that truly large integers may have to
Rcpp::NumericMatrix x(2,2); converted (rather crudely) to text and re-parsed. Using a different
x.fill(42); // or another value representation as for example from the GNU Multiple Precision
Rcpp::List dimnms = // list with 2 vecs Arithmetic Library may be an alternative.
Rcpp::List::create( // with static names
Rcpp::CharacterVector::create("cc", "dd"), 3.10. What LaTeX packages do I need to typeset the vignettes.
Rcpp::CharacterVector::create("ee", "ff")
); I would like to typeset the vignettes. What do I need?
// and assign it The TeXLive distribution seems to get bigger and bigger. What
x.attr("dimnames") = dimnms; you need to install may depend on your operating system.
return(x); Specific per-platform notes:

fun <- cxxfunction(signature(), • Windows users probably want the MiKTeX. Suggestions for a
body=src, plugin="Rcpp") more detailed walk through would be appreciated.
fun() • OS X users seem to fall into camps which like or do not like
brew / homebrew. One suggestion was to install MacTeX
The same logic, but used with Rcpp Attributes: but at approximately 2.5gb (as of January 2016) this is not
lightweight.
#include <Rcpp.h> • Linux users probably want the full TeXLive set from their distri-
bution. On Debian these packages are installed to build the R
// [[Rcpp::export]] package itself: texlive-base, texlive-latex-base,
Rcpp::List fun(void) { texlive-generic-recommended,
Rcpp::NumericMatrix x(2,2); texlive-fonts-recommended,
x.fill(42); // or another value texlive-fonts-extra, texlive-extra-utils,
Rcpp::List dimnms = // list with 2 vecs texlive-latex-recommended,
Rcpp::List::create( // with static names texlive-latex-extra. Using texlive-full may be
Rcpp::CharacterVector::create("cc", "dd"), a shortcut. Fedora and other distributions should have similar
Rcpp::CharacterVector::create("ee", "ff")); packages.
// and assign it
x.attr("dimnames") = dimnms; 3.11. Why is there a limit of 20 on some constructors.
return(x);
} Ok, I would like to pass N object but you only allow 20.
How come?
3.9. Why can long long types not be cast correctly. That is a good In essence, and in order to be able to compile it with the largest
and open question. We rely on the basic R types, notably integer number of compilers, Rcpp is constrained by the older C++ stan-
and numeric. These can be cast to and from C++ types without dards which do not support variadic function arguments. So we

8 | https://cran.r-project.org/package=Rcpp Eddelbuettel and François


actually use macros and code generator scripts to explicitly enu- 3.13. Can I use C++11, C++14, C++17, . . . with Rcpp. But of course.
merate arguments, and that number has to stop at some limit. We In a nutshell, this boils down to what your compiler supports, and
chose 20. also what R supports. We expanded a little on this in Rcpp Gallery
A good discussion is available at this StackOverflow question article providing more detail. What follows in an abridged sum-
concering data.frame creation with Rcpp. One solution offers a cus- mary.
tom ListBuilder class to circumvent the limit; another suggests You can always locally set appropriate PKG_CXXFLAGS as an
to simply nest lists. environment variable, or via ~/.R/Makevars. You can also plugins
and/or R support from src/Makevars:
3.12. Can I use default function parameters with Rcpp. Yes, you
can use default parameters with some limitations. The limitations • C++11: has been supported since early 2013 via a plugin se-
are mainly related to string literals and empty vectors. This is what lecting the language standard which is useful for sourceCpp()
is currently supported: etc. For packages, R has supported it since R 3.1.0 which
added the option to select the language standard via CXX_STD
• String literals delimited by quotes (e.g. "foo") = CXX11. As of early 2017, over 120 packages on CRAN use
• Integer and Decimal numeric values (e.g. 10 or 4.5) this.
• Pre-defined constants including: • C++14: has been supported since early 2016 via a plugin se-
lecting the language standard which is useful for sourceCpp()
– Booleans: true and false etc. For packages, R supports it since R 3.4.0 adding the option
– Null Values: R_NilValue, NA_STRING, NA_INTEGER, to select the language standard via CXX_STD = CXX14.
NA_REAL, and NA_LOGICAL. • C++17: is itself more experimental now, but if you have a
compiler supporting (at least parts of) it, you can use it via
• Selected vector types can be instantiated using the empty form plugin (starting with Rcpp 0.12.10) for use via sourceCpp(),
of the ::create static member function. or via PKG_CXXFLAGS or other means to set compiler options.
R support may be available at a later date.
– CharacterVector, IntegerVector, and
NumericVector
3.14. How do I use it within (Python’s) Conda setup?. In a com-
• Matrix types instantiated using the rows, cols constructor ment to issue ticket #770 it is stated that running
Rcpp::<Type>Matrix n(rows,cols)
conda install gxx_linux-64
– CharacterMatrix, IntegerMatrix, and
NumericMatrix helps within this environment as it installs the corresponding
x86_64-conda_cos6-linux-gnu-c++ compiler. Documentation
To illustrate, please consider the following example that pro- for this and other systems is provided at this page.
vides a short how-to:

#include <Rcpp.h> 4. Support

// [[Rcpp::export]] 4.1. Is the API documented. You bet. We use doxygen to generate
void sample_defaults( html, latex and man page documentation from the source. The
NumericVector x = html documentation is available for browsing, as a very large pdf
NumericVector::create(), // Size 0 vector file, and all three formats are also available a zip-archives: html,
bool bias = true, // Set to true latex, and man.
std::string method =
"rcpp rules!") { // Set string 4.2. Does it really work. We take quality seriously and have devel-
opped an extensive unit test suite to cover many possible uses of
Rcpp::Rcout << "x size: " << x.size() << ", "; the Rcpp API.
Rcpp::Rcout << "bias value: " << bias << ", "; We are always on the look for more coverage in our testing.
Rcpp::Rcout << "method value: " << "."; Please let us know if something has not been tested enough.

}
4.3. Where can I ask further questions. The Rcpp-devel mailing
/*** R list hosted at R-forge is by far the best place. You may also want
sample_defaults() # all defaults to look at the list archives to see if your question has been asked
sample_defaults(1:5) # supply x values before.
You can also use StackOverflow via its ‘rcpp’ tag.
sample_defaults(bias = FALSE, # supply bool
method = "Rlang") # and string 4.4. Where can I read old questions and answers. The normal
*/ Rcpp-devel mailing list hosting at R-forge contains an archive,
which can be searched via swish.
Note: In cpp, the default bool values are true and false Alternatively, one can also use Mail-Archive on Rcpp-devel
whereas in R the valid types are TRUE or FALSE. which offers web-based interfaces, including searching.

Eddelbuettel and François Rcpp Vignette | July 20, 2019 | 9


4.5. I like it. How can I help. We maintain a list of open issues in R object. Thus, if an operation is performed on the Rcpp object,
the Github repository. We welcome pull requests and suggest that such as adding 1 to each element, the operation also updates the
code submissions come corresponding unit tests and, if applicable, R object causing the change to be propagated to R’s interactive
documentation. environment.
If you are willing to donate time and have skills in C++, let us #include <Rcpp.h>
know. If you are willing to donate money to sponsor improvements,
let us know too. // [[Rcpp::export]]
You can also spread the word about Rcpp. There are many void implicit_ref(Rcpp::NumericVector X) {
packages on CRAN that use C++, yet are not using Rcpp. You could X = X + 1.0;
blog about it, or get the word out otherwise. }
Last but not least the Rcpp Gallery is open for user contributions.
// [[Rcpp::export]]
4.6. I don’t like it. How can I help. It is very generous of you to still void explicit_ref(Rcpp::NumericVector& X) {
want to help. Perhaps you can tell us what it is that you dislike. X = X + 1.0;
We are very open to constructive criticism. }

4.7. Can I have commercial support for Rcpp. Sure you can. Just R use
send us an email, and we will be happy to discuss the request.
a <- 1.5:4.5
4.8. I want to learn quickly. Do you provide training courses. Yes. b <- 1.5:4.5
Just send us an email. implicit_ref(a)
a
4.9. Where is the code repository. From late 2008 to late 2013, we # [1] 2.5 3.5 4.5 5.5
used the Subversion repository at R-Forge which contained Rcpp explicit_ref(b)
and a number of related packages. It still has the full history as b
well as number of support files. # [1] 2.5 3.5 4.5 5.5
We have since switched to a Git repository at Github for Rcpp
(as well as for RcppArmadillo and RcppEigen). 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
Rcpp:clone(). In this case, the cloned object has no link to the
5. Known Issues
original R object. However, there is a time cost associated with
Contained within this section is a list of known issues regarding this procedure as new memory must be allocated and the previous
Rcpp. The issues listed here are either not able to be fixed due values must be copied over. The second exception, which was
to breaking application binary interface (ABI), would impact the previously foreshadowed, is encountered when Rcpp and R object
ability to reproduce pre-existing results, or require significant work. types do not match. One frequent example of this case is when the
Generally speaking, these issues come to light only when pushing R object generated from seq() or a:b reports a class of "integer"
the edge capabilities of Rcpp. while the Rcpp object is setup to receive the class of "numeric"
as its object is set to NumericVector or NumericMatrix. In such
5.1. Rcpp changed the (const) object I passed by value. Rcpp ob- cases, this would lead to a new SEXP object being created behind the
jects are wrappers around the underlying R objects’ SEXP, or S- scenes and, thus, there would not be a link between the Rcpp object
expression. The SEXP is a pointer variable that holds the location and R object. So, any changes in C++ would not be propagated to
of where the R object data has been stored (R Core Team, 2018b, R unless otherwise specified.
Section 1.1). That is to say, the SEXP does not hold the actual data
#include <Rcpp.h>
of the R object but merely a reference to where the data resides.
When creating a new Rcpp object for an R object to enter C++, this
// [[Rcpp::export]]
object will use the same SEXP that powers the original R object
void int_vec_type(Rcpp::IntegerVector X) {
if the types match otherwise a new SEXP must be created to be
X = X + 1.0;
type safe. In essence, the underlying SEXP objects are passed by
}
reference without explicit copies being made into C++. We refer to
this arrangement as a proxy model.
// [[Rcpp::export]]
As for the actual implementation, there are a few conse-
void num_vec_type(Rcpp::NumericVector X) {
quences of the proxy model. The foremost consequence within
X = X + 1.0;
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:
R use:
void implicit_ref(NumericVector X); a <- 1:5
void explicit_ref(NumericVector& X); b <- 1:5
class(a)
In particular, when one is passing by value what occurs is the # [1] "integer"
instantiation of the new Rcpp object that uses the same SEXP for int_vec_type(a)
the R object. As a result, the Rcpp object is “linked” to the original

10 | https://cran.r-project.org/package=Rcpp Eddelbuettel and François


a # variable a changed as a side effect std::string s; // define storage
# [1] 2 3 4 5 6 s = X[0]; // assign from CharacterVector
num_vec_type(b)
b # b unchanged as copy was made for numeric return s;
# [1] 1 2 3 4 5 }
With this being said, there is one last area of contention with the If one were to use a direct allocation and assignment strategy,
proxy model: the keyword const. The const declaration indicates e.g. std::string s = X[0], this would result in the compiler
that an object is not allowed to be modified by any action. Due triggering a conversion error on some platforms. The error would
to the way the proxy model paradigm works, there is a way to be similar to:
“override” the const designation. Simply put, one can create a new error: no viable conversion from ’Proxy’
Rcpp object without the const declaration from a pre-existing (aka ’string_proxy<16>’) to ’std::string’
one. As a result, the new Rcpp object would be allowed to be (aka ’basic_string<char, char_traits<char>,
modified by the compiler and, thus, modifying the initial SEXP allocator<char> >’)
object. Therefore, the initially secure R object would be altered.
To illustrate this phenomenon, consider the following scenario: The second way to help the compiler is to use an explicit Rcpp
#include <Rcpp.h> type conversion function, if one were to exist. Examples of Rcpp
type conversion functions include as<T>(), .get() for cumsum(),
// [[Rcpp::export]] is_true() and is_false() for any() or all().
Rcpp::IntegerVector const_override_ex(
const Rcpp::IntegerVector& X) { 5.3. Using operator= with a scalar replaced the object instead of
filling element-wise. Assignment using the operator= with either
Rcpp::IntegerVector Y(X); // Create object Vector and Matrix classes will not elicit an element-wise fill.
// from SEXP If you seek an element-wise fill, then use the .fill() member
method to propagate a single value throughout the object. With
Y = Y * 2; // Modify new object this being said, the behavior of operator= differs for the Vector
and Matrix classes.
return Y; // Return new object The implementation of the operator= for the Vector class will
} replace the existing vector with the assigned value. This behavior is
valid even if the assigned value is a scalar value such as 3.14 or 25 as
R use: the object is cast into the appropriate Rcpp object type. Therefore,
if a Vector is initialized to have a length of 10 and a scalar is
x <- 1:10 # an integer sequence assigned via operator=, then the resulting Vector would have a
# returning an altered value length of 1. See the following code snippet for the aforementioned
const_override_ex(x) behavior.
# [1] 2 4 6 8 10 12 14 16 18 20
# but the original value is altered too! #include <Rcpp.h>
x
# [1] 2 4 6 8 10 12 14 16 18 20 // [[Rcpp::export]]
void vec_scalar_assign(int n, double fill_val) {
So we see that with SEXP objects, the const declaration can be Rcpp::NumericVector X(n);
circumvented as it is really a pointer to the underlying R object. Rcpp::Rcout << "Value of Vector " <<
"on Creation: " <<
5.2. Issues with implicit conversion from an Rcpp object to a std::endl << X << std::endl;
scalar or other Rcpp object. Not all Rcpp expressions are directly
compatible with operator=. Compability issues stem from many X = fill_val;
Rcpp objects and functions returning an intermediary result which
requires an explicit conversion. In such cases, the user may need Rcpp::Rcout << "Value of Vector " <<
to assist the compiler with the conversion. "after Assignment: " <<
There are two ways to assist with the conversion. The first std::endl << X << std::endl;
is to construct storage variable for a result, calculate the result, }
and then store a value into it. This is typically what is needed
when working with Character<Type> and String in Rcpp due to R use:
the Rcpp::internal::string_proxy class. Within the following vec_scalar_assign(5L, 3.14)
code snippet, the aforementioned approach is emphasized: # Value of Vector on Creation:
#include <Rcpp.h> # 0 0 0 0 0
# Value of Vector after Assignment:
// [[Rcpp::export]] # 3.14
std::string explicit_string_conv(
Rcpp::CharacterVector X) { Now, the Matrix class does not define its own operator= but
instead uses the Vector class implementation. This leads to un-
expected results while attempting to use the assignment operator

Eddelbuettel and François Rcpp Vignette | July 20, 2019 | 11


with a scalar. In particular, the scalar will be coerced into a square #else
Matrix and then assigned. For an example of this behavior, con- return false;
sider the following code: #endif
}
#include <Rcpp.h>
R use:
// [[Rcpp::export]] test_long_vector_support()
void mat_scalar_assign(int n, double fill_val) { # [1] TRUE
Rcpp::NumericMatrix X(n, n);
Rcpp::Rcout << "Value of Matrix " << The remaining two options are for users who have opted to
"on Creation: " << embed Rcpp code within an R package. In particular, the sec-
std::endl << X << std::endl; ond option requires adding CXX_STD = CXX11 to a Makevars file
found in the /src directory. Finally, the third option is to add
X = fill_val; SystemRequirements:C++11 in the package’s DESCRIPTION file.
Please note that the support for C++11 prior to R v3.3.0 on
Rcpp::Rcout << "Value of Matrix " << Windows is limited. Therefore, plan accordingly if the goal is to
"after Assignment: " << support older versions of R.
std::endl << X << std::endl;
} 5.5. Sorting with STL on a CharacterVector produces problem-
atic results. The Standard Template Library’s (STL) std::sort
R use: algorithm performs adequately for the majority of Rcpp data
types. The notable exception that makes what would oth-
mat_scalar_assign(2L, 3.0)
erwise be a universal quantifier into an existential quantifier
# Value of Matrix on Creation:
is the CharacterVector data type. Chiefly, the issue with
# 0.00000 0.00000
sorting strings is related to how the CharacterVector relies
# 0.00000 0.00000
upon the use of Rcpp::internal::string_proxy. In particular,
#
Rcpp::internal::string_proxy is not MoveAssignable since
# Value of Matrix after Assignment:
the left hand side of operator=(const string_proxy \&rhs) is
# 0.00000 0.00000 0.00000
not viewed as equivalent to the right hand side before the operation
# 0.00000 0.00000 0.00000
(ISO/IEC, 2011, p. 466, Table 22). This further complicates mat-
# 0.00000 0.00000 0.00000
ters when using CharacterVector with std::swap, std::move,
std::copy and their variants.
5.4. Long Vector support on Windows. Prior to R’s 3.0.0, the To avoid unwarranted pain with sorting, the preferred approach
largest vector one could obtain was at most 231 − 1 elements. With is to use the .sort() member function of Rcpp objects. The
the release of R’s 3.0.0, long vector support was added to allow member function correctly applies the sorting procedure to Rcpp
for largest vector possible to increase up to 252 elements on x64 objects regardless of type. Though, sorting is slightly problematic
bit operating systems (c.f. Long Vectors help entry). Once this was due to locale as explained in the next entry. In the interim, the
established, support for long vectors within the Rcpp paradigm following code example illustrates the preferred approach alongside
was introduced with Rcpp version 0.12.0 (c.f Rcpp 0.12.0 annouce- the problematic STL approach:
ment).
However, the requirement for using long vectors in Rcpp neces- #include <Rcpp.h>
sitates the presence of compiler support for the R_xlen_t, which
is platform dependent on how ptrdiff_t is implemented. Unfor- // [[Rcpp::export]]
tunately, this means that on the Windows platform the definition of Rcpp::CharacterVector preferred_sort(
R_xlen_t is of type long instead of long long when compiling Rcpp::CharacterVector x) {
under the C++98 specification. Therefore, to solve this issue one
must compile under the specification for C++11 or later version. Rcpp::CharacterVector y = Rcpp::clone(x);
There are three options to trigger compilation with C++11. The y.sort();
first – and most likely option to use – will be the plugin sup-
port offered by Rcpp attributes. This is engaged by adding // return y;
[[Rcpp::plugins(cpp11)]] to the top of the C++ script. For di- }
agnostic and illustrativative purposes, consider the following code
which checks to see if R_xlen_t is available on your platform: // [[Rcpp::export]]
Rcpp::CharacterVector stl_sort(
#include <Rcpp.h> Rcpp::CharacterVector x) {
// Force compilation mode to C++11
// [[Rcpp::plugins(cpp11)]] Rcpp::CharacterVector y = Rcpp::clone(x);
std::sort(y.begin(), y.end());
// [[Rcpp::export]]
bool test_long_vector_support() { return y;
#ifdef RCPP_HAS_LONG_LONG_TYPES }
return true;
R use:

12 | https://cran.r-project.org/package=Rcpp Eddelbuettel and François


set.seed(123) tools::package_native_routine_registration_skeleton(),
(X <- sample(c(LETTERS[1:5], letters[1:6]), 11)) which crawls through usages of .Call() in the R/ source files of
# [1] "C" "f" "B" "a" "e" "E" "D" "d" "c" "A" "b" the package to figure out what routines need to be registered. If
preferred_sort(X) an older RcppExports.R file is discovered, its out-of-date symbol
# [1] "A" "B" "C" "D" "E" "a" "b" "c" "d" "e" "f" names get picked up, and registration rules for those symbols get
stl_sort(X) written as well. This will register more symbols for the package
# [1] "f" "f" "f" "f" "f" "f" "f" "f" "f" "C" "f" than are actually defined, leading to an error. This point has
been discussed at some length both in the GitHub issue tickes, on
In closing, the results of using the STL approach do change StackOverflow and elsewhere.
depending on whether libc++ or libstdc++ standard library is So if your autogenerated file fails, and a symbols not
used to compile the code. When debugging, this does make the found error is reported by the linker, consider running
issue particularly complex to sort out. Principally, compilation compileAttributes() twice. Deleting R/RcppExports.R and
with libc++ and STL has been shown to yield the correct results. src/RcppExports.cpp may also work.
However, it is not wise to rely upon this library as a majority of
code is compiled against libstdc++ as it more complete.
References
5.6. Lexicographic order of string sorting differs due to capitaliza-
Allaire JJ, Eddelbuettel D, François R (2018). Rcpp Attributes. Vignette included
tion. Comparing strings within R hinges on the ability to process
in R package Rcpp, URL http://CRAN.R-Project.org/package=Rcpp.
the locale or native-language environment of the string. In R, there Bates D, Eddelbuettel D (2013). “Fast and Elegant Numerical Linear Algebra
is a function called Scollate that performs the comparison on Using the RcppEigen Package.” Journal of Statistical Software, 52(5), 1–24.
locale. Unfortunately, this function has not been made publicly URL http://www.jstatsoft.org/v52/i05/.
available and, thus, Rcpp does not have access to it within its imple- Eddelbuettel D (2013). Seamless R and C++ Integration with Rcpp. Use R!
mentation of StrCmp. As a result, strings that are sorted under the Springer, New York. ISBN 978-1-4614-6867-7.
.sort() member function are ordered improperly. Specifically, if Eddelbuettel D, Balamuta JJ (2017). “Extending R with C++:
capitalization is present, then capitalized words are sorted together A Brief Introduction to Rcpp.” PeerJ Preprints, 5. doi:
followed by the sorting of lowercase words instead of a mixture 10.7287/peerj.preprints.3188v1/.
Eddelbuettel D, Balamuta JJ (2018). “Extending R with C++: A Brief
of capitalized and lowercase words. The issue is illustrated by the
Introduction to Rcpp.” The American Statistician, 72(1). doi:
following code example:
10.1080/00031305.2017.1375990.
#include <Rcpp.h> Eddelbuettel D, François R (2011). “Rcpp: Seamless R and C++ Integration.”
Journal of Statistical Software, 40(8), 1–18. URL http://www.jstatsoft.org/v40/
i08/.
// [[Rcpp::export]]
Eddelbuettel D, François R, Allaire J, Ushey K, Kou Q, Russel N, Chambers J,
Rcpp::CharacterVector rcpp_sort( Bates D (2019a). Rcpp: Seamless R and C++ Integration. R package version
Rcpp::CharacterVector X) { 1.0.2, URL http://CRAN.R-Project.org/package=Rcpp.
X.sort(); Eddelbuettel D, François R, Bates D, Ni B (2019b). RcppArmadillo: Rcpp
return X; integration for Armadillo templated linear algebra library. R package version
} 0.9.600.4.0, URL http://CRAN.R-Project.org/package=RcppArmadillo.
Eddelbuettel D, Sanderson C (2014). “RcppArmadillo: Accelerating R with
R use: High-Performance C++ Linear Algebra.” Computational Statistics and Data
Analysis, 71, 1054–1063. doi:10.1016/j.csda.2013.02.005. URL
x <- c("B", "b", "c", "A", "a") http://dx.doi.org/10.1016/j.csda.2013.02.005.
sort(x) ISO/IEC (2011). “C++ 2011 Standard Document 14882:2011.” ISO/IEC Stan-
# [1] "a" "A" "b" "B" "c" dard Group for Information Technology / Programming Languages / C++.
rcpp_sort(x) URL http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?
# [1] "A" "B" "a" "b" "c" csnumber=50372.
R Core Team (2018a). R Installation and Administration. R Foundation for
Statistical Computing, Vienna, Austria. URL http://CRAN.R-Project.org/doc/
5.7. Package building fails with ‘symbols not found’. R 3.4.0 and manuals/R-admin.html.
later strongly encourage registering dynamically loadable symbols. R Core Team (2018b). R internals. R Foundation for Statistical Computing,
In the stronger form (where .registration=TRUE is added to the Vienna, Austria. URL http://CRAN.R-Project.org/doc/manuals/R-ints.html.
useDynLib() statement in NAMESPACE), only registered symbols R Core Team (2018c). Writing R extensions. R Foundation for Statistical
Computing, Vienna, Austria. URL http://CRAN.R-Project.org/doc/manuals/
can be loaded. This is fully supported by Rcpp 0.12.12 and later,
R-exts.html.
and the required code is added to src/RcppExports.cpp.
Sanderson C (2010). “Armadillo: An open source C++ Algebra Library for Fast
However, the transition from the previously gener- Prototyping and Computationally Intensive Experiments.” Technical report,
ated file src/RcppExports.cpp to the new one may NICTA. URL http://arma.sf.net.
require running compileAttributes() twice (which Sklyar O, Murdoch D, Smith M, Eddelbuettel D, François R (2018). inline: Inline
does not happen when, e.g., devtools is used). When C, C++, Fortran function calls from R. R package version 0.3.15, URL
Rcpp::compileAttributes() is called, it also calls http://CRAN.R-Project.org/package=inline.

Eddelbuettel and François Rcpp Vignette | July 20, 2019 | 13

You might also like