Rcpp 不会导出内联 void 函数

问题描述 投票:0回答:1

简单的代码文件test2.cpp是

double tau;

// [[Rcpp::export]]
inline void set_tau(double t) {
  tau = t;
}

// [[Rcpp::export]]
inline double get_tau() {
  return tau;
}

它不会用 Rcpp::sourceCpp("./src/test2.cpp") 编译,但删除 inline 关键字后代码可以编译并运行:代码文件 test3.cpp 是

double tau;

// [[Rcpp::export]]
void set_tau(double t) {
  tau = t;
}

// [[Rcpp::export]]
double get_tau() {
  return tau;
}

Rcpp::sourceCpp("./src/test2.cpp") 抛出错误

test2.cpp: In function ‘SEXPREC* sourceCpp_1_set_tau(SEXP)’:
test2.cpp:27:44: error: invalid use of void expression
  27 |     rcpp_result_gen = Rcpp::wrap(set_tau(t));
      |                                            ^
make: *** [/usr/lib/R/etc/Makeconf:177: test2.o] Error 1
Error in Rcpp::sourceCpp("./src/test2.cpp") : 
  Error 1 occurred building shared library.
>

但是代码可以从命令行 g++ test2.cpp -g -c -o test2.o 正常编译,其中 g++ 是版本 9.4。另外 test3.cpp 编译并运行良好

> Rcpp::sourceCpp("./src/test3.cpp")
> set_tau(20)
> get_tau()
[1] 20
> 

看来 Rcpp 版本 1.0.11 无法处理内联 void 函数。他们有解决方法吗?例如,g++ -o3 会生成一个没有 inline 关键字的内联函数吗?

function inline rcpp void
1个回答
0
投票

您面临的问题可能是由于

inline
关键字在 C++ 和 R 中的处理方式不同。在 C++ 中,
inline
是要求编译器考虑内联函数的请求,但它并不保证该函数将被内联。然而,在 R 中,
inline
是保留字,不能用作函数名。

当您使用

Rcpp::sourceCpp()
时,R 解析器首先处理 C++ 代码,然后再将其传递给 C++ 编译器。 R 解析器看到
inline
关键字并将其视为无效函数名称,从而导致您遇到的错误。

对于您的解决方法问题,您可以考虑以下几种选择:

  1. 删除

    inline
    关键字:正如您已经发现的那样,从 C++ 代码中删除
    inline
    关键字可以解决该问题,并且代码可以通过
    Rcpp::sourceCpp()
    正确编译和运行。这是最简单的解决方案,但这意味着编译器将根据自己的启发来决定是否内联函数。

  2. 使用

    __attribute__((always_inline))
    而不是
    inline
    :这是一项 C++11 功能,明确告诉编译器始终内联函数,无论其大小或其他因素如何。但是,请记住,过多的内联会增加代码大小,并在某些情况下可能降低性能。

  3. 启用链接时优化 (LTO):如果您使用的是最新版本的 GCC 或 Clang,则可以通过将

    -flto
    标志传递给编译器来启用链接时优化 (LTO)。 LTO 执行整个程序优化,包括跨翻译单元的潜在内联函数。但是,启用 LTO 会增加编译时间和二进制大小。

  4. 使用

    __forceinline
    关键字(仅限 MSVC):如果您使用的是 Microsoft Visual C++ (MSVC),则可以使用
    __forceinline
    关键字而不是
    inline
    来显式请求函数内联。但是,这是一个非标准扩展,无法与其他编译器一起使用。

一般来说,建议避免过度使用

inline
,除非您有特定的性能原因这样做,并且已经仔细测量和分析了您的代码。现代编译器通常比人类更擅长决定内联哪些函数,不必要的内联会增加代码大小并可能降低性能。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.