有没有办法让 Rcpp 停止定义 NDEBUG?

Is there any way to make Rcpp stop defining NDEBUG?

Why does assert not work here?

^ 显然,Rcpp 有自己定义 NDEBUG 的习惯,即使不是我自己定义的。

m@m-X555LJ:~/wtfdir$ cat WTF.r
#!/usr/bin/Rscript

library(Rcpp)

sourceCpp("WTF.cpp")
m@m-X555LJ:~/wtfdir$ cat WTF.cpp
#ifdef NDEBUG
#error WTF I did not define this
#endif
m@m-X555LJ:~/wtfdir$ ./WTF.r
WTF.cpp:2:2: error: #error WTF I did not define this
 #error WTF I did not define this
  ^~~~~
make: *** [WTF.o] Error 1
g++  -I"/usr/share/R/include" -DNDEBUG   -I"/home/m/R/x86_64-pc-linux-gnu-library/3.5/Rcpp/include" -I"/home/m/wtfdir"    -fpic  -g -O2 -fdebug-prefix-map=/build/r-base-3U0YWo/r-base-3.5.3=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -g  -c WTF.cpp -o WTF.o
/usr/lib/R/etc/Makeconf:172: recipe for target 'WTF.o' failed
Error in sourceCpp("WTF.cpp") : Error 1 occurred building shared library.
Execution halted
m@m-X555LJ:~/wtfdir$ 

我链接的 SO 问题的答案解释了 (a) 禁止在上传到 CRAN 的包中调用 assert,因为 (b) C++ 代码不应停止 R 代码,并且 (c)我应该抛出异常,由 Rcpp 捕获。

但是:

有没有办法让 Rcpp 停止定义 NDEBUG?或者我应该简单地删除所有 asserts 和任何依赖于 NDEBUG 的东西并切换到抛出异常并停止抱怨?

首先,如果您在 R 自己的 Makeconfgrep for NDEBUG(我们可以通过来自 /etc/R 的便捷软链接访问 Debian 及其衍生产品我如何设置 .deb 包):

edd@rob:~$ grep NDEBUG /etc/R/Makeconf 
R_XTRA_CPPFLAGS =  -I"$(R_INCLUDE_DIR)" -DNDEBUG
ALL_CPPFLAGS =  -I"$(R_INCLUDE_DIR)" -DNDEBUG $(PKG_CPPFLAGS) $(CLINK_CPPFLAGS) $(CPPFLAGS)
edd@rob:~$ 

根据您的问题,您看到它是由 R 而不是 Rcpp 强加的。所以你的假设是错误的。它在 您的 本地控制之下:只需在 您的 机器上编辑 R 的 Makeconf。您只是无法为您的代码的假设其他用户自动执行此操作。但是根据你的问题,这似乎并不是一个直接的问题。

其次,如果你想要一个特定的 #define 你可以直接定义它:

代码

#include <Rcpp.h>

// [[Rcpp::export]]
void foo() {

#ifdef DEBUG
  Rcpp::Rcout << "foo: Debug mode" << std::endl;
#endif

  Rcpp::Rcout << "foo: Hello, world" << std::endl;
}

#define DEBUG 1

// [[Rcpp::export]]
void bar() {

#ifdef DEBUG
  Rcpp::Rcout << "bar: Debug mode" << std::endl;
#endif

  Rcpp::Rcout << "bar: Hello, world" << std::endl;
}


/*** R
foo()
bar()
*/

输出

R> sourceCpp("~/git/Whosebug/56209693/answer.cpp")

R> foo()
foo: Hello, world

R> bar()
bar: Debug mode
bar: Hello, world
R> 

定义其他日志记录宏如 DEBUGFATAL 或 ... 是很常见的] 工具)关闭 assert

第三个也是最后一个,您可以按照this question中的方法暂时取消定义NDEBUG以包含cassert,然后重新定义它。 给你 assert() 并终止你的会话,正如我检查的那样。不是我使用 R 进行调试的方法,但嘿,如果你真的必须...