I have recently started using a machine with Ubuntu 22.04 and I find that my existing (windows) .cpp
files are no longer compiling with sourceCpp
. The issue is that I require a compilation with at least C++14
, and in fact I can successful compile the files using sourceCpp
if I explicitly set the flag // [[Rcpp::plugins("cpp14")]]
.
My question is why R has chosen to use a lower version of C++
when C++17
is available and seems to be the default in simple programs? Compare the following two sample .cpp
files, which seem to differ only in the inclusion of the RcppArmadillo
libraries:
# test_stan.cpp
// [[Rcpp::depends(rstan)]]
#include <stan/math.hpp>
#include <iostream>
// [[Rcpp::export]]
int simple() {
std::cout << "log normal(1 | 2, 3)="
<< stan::math::normal_log(1, 2, 5)
<< std::endl;
return 0;
}
# test_stan_with_more_complicated...
// [[Rcpp::depends(rstan)]]
#include <stan/math.hpp>
#include <iostream>
#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]
using namespace Rcpp;
// [[Rcpp::export]]
int simple() {
std::cout << "log normal(1 | 2, 3)="
<< stan::math::normal_log(1, 2, 5)
<< std::endl;
return 0;
}
Running sourceCpp
results in the following calls to the C++ compiler respectively:
using C++ compiler: ‘g++ (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0’ g++
-std=gnu++17 -I"/usr/share/R/include" -DNDEBUG -I"/usr/local/lib/R/site-library/Rcpp/include/" -I"/usr/local/lib/R/site-library/RcppEigen/include/" -I"/usr/local/lib/R/site-library/RcppEigen/include/unsupported" -I"/usr/local/lib/R/site-library/BH/include" -I"/usr/local/lib/R/site-library/StanHeaders/include/src/" -I"/usr/local/lib/R/site-library/StanHeaders/include/" -I"/usr/local/lib/R/site-library/RcppParallel/include/" -I"/usr/local/lib/R/site-library/rstan/include" -DEIGEN_NO_DEBUG -DBOOST_DISABLE_ASSERTS -DBOOST_PENDING_INTEGER_LOG2_HPP -DSTAN_THREADS -DUSE_STANC3 -DSTRICT_R_HEADERS -DBOOST_PHOENIX_NO_VARIADIC_EXPRESSION -D_HAS_AUTO_PTR_ETC=0 -include ‘/usr/local/lib/R/site-library/StanHeaders/include/stan/math/prim/fun/Eigen.hpp’
-D_REENTRANT -DRCPP_PARALLEL_USE_TBB=1 -I"/usr/local/lib/R/site-library/Rcpp/include" -I"/usr/local/lib/R/site-library/rstan/include" -I"/home/rdpdp/Desktop/data/debug_gcc_version" -fpic -g -O2 -ffile-prefix-map=/build/r-base-H8urij/r-base-4.4.0=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -c test_stan.cpp -o test_stan.o
and
g++ -std=gnu++11 -I"/usr/share/R/include" -DNDEBUG
-I"/usr/local/lib/R/site-library/Rcpp/include/" -I"/usr/local/lib/R/site-library/RcppEigen/include/" -I"/usr/local/lib/R/site-library/RcppEigen/include/unsupported" -I"/usr/local/lib/R/site-library/BH/include" -I"/usr/local/lib/R/site-library/StanHeaders/include/src/" -I"/usr/local/lib/R/site-library/StanHeaders/include/" -I"/usr/local/lib/R/site-library/RcppParallel/include/" -I"/usr/local/lib/R/site-library/rstan/include" -DEIGEN_NO_DEBUG -DBOOST_DISABLE_ASSERTS -DBOOST_PENDING_INTEGER_LOG2_HPP -DSTAN_THREADS -DUSE_STANC3 -DSTRICT_R_HEADERS -DBOOST_PHOENIX_NO_VARIADIC_EXPRESSION -D_HAS_AUTO_PTR_ETC=0 -include ‘/usr/local/lib/R/site-library/StanHeaders/include/stan/math/prim/fun/Eigen.hpp’
-D_REENTRANT -DRCPP_PARALLEL_USE_TBB=1 -I../inst/include -fopenmp -I"/usr/local/lib/R/site-library/Rcpp/include" -I"/usr/local/lib/R/site-library/rstan/include" -I"/usr/local/lib/R/site-library/RcppArmadillo/include" -I"/home/rdpdp/Desktop/data/debug_gcc_version" -fpic -g -O2 -ffile-prefix-map=/build/r-base-H8urij/r-base-4.4.0=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -c test_stan_with_more_complicated_includes.cpp -o test_stan_with_more_complicated_includes.o
Apart from addition RcppArmadillo
and fopenmp
flag, the only difference seems to be in the C++ version:
My machine has the following compilers:
dpkg --list | grep compiler
ii g++ 4:11.2.0-1ubuntu1 amd64 GNU C++ compiler
ii g++-11 11.4.0-1ubuntu1~22.04 amd64 GNU C++ compiler
ii gcc 4:11.2.0-1ubuntu1 amd64 GNU C compiler
ii gcc-11 11.4.0-1ubuntu1~22.04 amd64 GNU C compiler
ii gfortran 4:11.2.0-1ubuntu1 amd64 GNU Fortran 95 compiler
ii gfortran-11 11.4.0-1ubuntu1~22.04 amd64 GNU Fortran compiler
ii libllvm14:amd64 1:14.0.0-1ubuntu1.1 amd64 Modular compiler and toolchain technologies, runtime library
ii libllvm15:amd64 1:15.0.7-0ubuntu0.22.04.3 amd64 Modular compiler and toolchain technologies, runtime library
ii libxkbcommon0:amd64 1.4.0-1 amd64 library interface to the XKB compiler - shared library
ii rpcsvc-proto 1.4.2-0ubuntu6 amd64 RPC protocol compiler and definitions
R sessionInfo()
excerpt is:
R version 4.4.0 (2024-04-24)
Platform: x86_64-pc-linux-gnu
Running under: Ubuntu 22.04.4 LTS
Matrix products: default
BLAS: /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.10.0
LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.10.0
attached base packages:
[1] stats graphics grDevices utils datasets methods base
loaded via a namespace (and not attached):
[1] vctrs_0.6.5 cli_3.6.2 rlang_1.1.3 generics_0.1.3
[5] jsonlite_1.8.8 RcppParallel_5.1.7 glue_1.7.0 colorspace_2.1-0
[9] rstan_2.32.6 gridExtra_2.3 pkgbuild_1.4.4 stats4_4.4.0
[13] scales_1.3.0 fansi_1.0.6 StanHeaders_2.32.7 grid_4.4.0
[17] munsell_0.5.1 tibble_3.2.1 lifecycle_1.0.4 QuickJSR_1.1.3
[21] inline_0.3.19 compiler_4.4.0 codetools_0.2-19 dplyr_1.1.4
[25] pkgconfig_2.0.3 Rcpp_1.0.12 R6_2.5.1 tidyselect_1.2.1
[29] utf8_1.2.4 parallel_4.4.0 pillar_1.9.0 magrittr_2.0.3
[33] loo_2.7.0 tools_4.4.0 gtable_0.3.5 matrixStats_1.3.0
[37] ggplot2_3.5.1
2
Answers
The reason for this is the way that
RcppArmadillo
configures its C++ compilation settings. The default version withRcppArmadillo
isgnu++11
. The default setting fromRcppArmadillo
is applied byRcpp
.If you specifically want it to use another version of the C++ compiler then there are a couple of ways to do this:
CXX_STD
variable in the environment running R..cpp
file (just put this after the line// [[Rcpp::depends(RcppArmadillo)]]
).I don’t have
gnu++17
on my machine but both of the approaches above gavegnu++14
as the compiler for the latter.cpp
file provided.In general, this is set by R as described in Writing R Extensions. R has been moving up the default compilers since release R 4.0.0 and if I recall correctly has been at C++17 since maybe R 4.2.0.
In a fresh Docker container of Ubuntu 22.04 updated to R 4.4.0:
as expected as
gcc
/g++
version 11 is good enough. A good check is use a minimalRcppArmadillo
example such aswhich, when built via
Rcpp::sourceCpp("armaex.cpp", verbose=TRUE)
does get compiled via C++11 which looks like an oversight. In any event, you can override it easily for this use case too by setting a plugin as e.g. here for C++17:In the Docker container I use this shows more than a screen of detail (when
verbose=TRUE
is set) includingwhich shows that the setting takes effect overriding what the package (accidentally? over-eagerly?) sets.