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



为什么断言在这里不起作用?

^ 显然,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 捕获。

然而:

  • 我不想将我的代码上传到 CRAN; 相反,我正在编写代码供自己使用;
  • 即使我希望将其上传到 CRAN,我也可以在不NDEBUG的情况下自行编译它以进行测试,然后在上传到 CRAN 之前定义NDEBUG;
  • 由于 R 代码
  • 和C++代码都是出于相同的目的而编写的(我认为它们都是同一个程序),我实际上希望如果检测到其中任何部分的错误,整个程序都会爆炸; 如果代码有问题C++继续运行 R 代码对我来说毫无意义;
  • 由于我不知道将定义NDEBUG,我已经在我的代码中放置了相当多的assert,并且还通过std::cerr将诊断程序包装在#ifndef NDEBUG中; 这些显然不起作用;
  • 我不想无条件地抛出异常,因为有些assert计算量很大;
  • 截至目前,我的C++代码无论如何都会吹我的 R 代码,因为它崩溃了,我正在尝试调查这个问题,但我不能,因为我的诊断不起作用。

有没有办法让 Rcpp 停止定义NDEBUG?还是我应该简单地删除所有asserts和任何其他取决于NDEBUG的内容,并切换到抛出异常并停止抱怨?

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

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/stackoverflow/56209693/answer.cpp")
R> foo()
foo: Hello, world
R> bar()
bar: Debug mode
bar: Hello, world
R> 

定义其他日志记录宏(如DEBUGFATAL或 ...即使默认情况下 R(并且出于可理解的原因作为主要交互式工具)关闭assert,其行为也类似于断言。

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

相关内容

  • 没有找到相关文章

最新更新