You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ubuntu22.04中引入RcppArmadillo导致R用C++11而非C++17编译的原因?

Rcpp编译时C++版本差异的原因分析

问题背景

近期切换到Ubuntu 22.04系统后,发现Windows环境下的.cpp文件无法通过sourceCpp编译,排查后确认代码需要至少C++14版本支持,添加// [[Rcpp::plugins("cpp14")]]标记后可成功编译。

核心疑问:明明C17可用且在简单程序中是默认版本,为什么引入RcppArmadillo库后,R会选择更低的C版本?

对比示例代码

无RcppArmadillo的版本(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;
}

引入RcppArmadillo的版本

// [[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;
}

编译命令差异

运行sourceCpp后,两个文件的编译命令仅在C++版本和少量附加参数上存在区别:

无RcppArmadillo的编译命令

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

引入RcppArmadillo的编译命令

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

核心差异:前者使用-std=gnu++17,后者使用-std=gnu++11。

环境信息

编译器版本

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环境信息

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 

原因解析

这个问题的核心是Rcpp依赖包的C++版本声明优先级:

  1. 仅依赖rstan的代码中,rstan(通过StanHeaders)会主动设置C17作为编译标准——Stan从2.26版本起就要求C17支持,因此编译命令中会出现-std=gnu++17。
  2. 引入RcppArmadillo时,该包的默认编译标准为C11(部分旧版本或兼容性约束未更新配置)。Rcpp在处理多依赖时,会采用所有依赖中最低的兼容版本,或依赖包的声明会覆盖默认设置,最终导致编译标准被拉低到C11。

解决方法

  • 显式在代码开头添加// [[Rcpp::plugins("cpp14")]]或// [[Rcpp::plugins("cpp17")]],强制指定编译版本,覆盖依赖包的默认设置。
  • 更新RcppArmadillo到最新版本(部分新版本已调整默认C++版本),或修改其编译配置文件。

内容的提问来源于stack exchange,提问作者Alex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 01:17:33