有什么办法可以使Rcpp停止定义NDEBUG?

时间:2019-05-19 16:16:32

标签: c++ r rcpp ndebug

Why does assert not work here?

^显然,Rcpp习惯于自己定义def corsapp_route(path, origin=('127.0.0.1',), **options): """ Flask app alias with cors :return: """ def inner(func): def wrapper(*args, **kwargs): if request.method == 'OPTIONS': response = make_response() response.headers.add("Access-Control-Allow-Origin", ', '.join(origin)) response.headers.add('Access-Control-Allow-Headers', ', '.join(origin)) response.headers.add('Access-Control-Allow-Methods', ', '.join(origin)) return response else: result = func(*args, **kwargs) if 'Access-Control-Allow-Origin' not in result.headers: result.headers.add("Access-Control-Allow-Origin", ', '.join(origin)) return result wrapper.__name__ = func.__name__ if 'methods' in options: if 'OPTIONS' in options['methods']: return app.route(path, **options)(wrapper) else: options['methods'].append('OPTIONS') return app.route(path, **options)(wrapper) return wrapper return inner @corsapp_route('/', methods=['POST'], origin=['*']) def hello_world(): ... ,即使我自己没有定义。

NDEBUG

我链接说明的SO问题的答案说明:(a)禁止在上传到CRAN的程序包中调用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$ ,因为(b)C ++代码不应暂停R代码,而(c)我应该而是抛出Rcpp捕获的异常。

但是:

  • 我不希望将代码上传到CRAN;相反,我正在编写代码供自己使用;
  • 即使我希望将其上传到CRAN,出于测试目的,我也可以自己编写而不用assert进行编译,然后在上传到CRAN之前定义NDEBUG
  • 由于R代码和C ++代码都是由我自己编写的,目的是出于相同的目的(并且我认为它们都是同一程序),所以我实际上希望整个程序在出现任何错误时都会崩溃被检测到;如果C ++代码有故障,继续运行R代码对我来说毫无意义;
  • 由于我不知道会定义NDEBUG,因此我已经在代码中放入了许多NDEBUG,并且通过assert打印诊断信息也包裹在{{1}中} s;这些显然无法正常工作;
  • 我不想无条件地抛出异常,因为某些std::cerr的计算量很大;
  • 到目前为止,由于崩溃,我的C ++代码仍然反响了我的R代码,我正在尝试调查此问题,但由于诊断程序不起作用,我无法这样做。

有什么方法可以使Rcpp停止定义#ifndef NDEBUG?还是我应该简单地删除所有assert和所有依赖于NDEBUG的东西,然后转为引发异常并停止抱怨?

1 个答案:

答案 0 :(得分:4)

首先,如果您使用R自己的grep中的NDEBUG Makeconf(我们可以通过Debian及其衍生产品上的/etc/R上的便捷软链接访问它,原因是我设置了.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/stackoverflow/56209693/answer.cpp")

R> foo()
foo: Hello, world

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

定义其他日志记录宏(例如DEBUGFATAL或...)的行为很常见,即使默认情况下R(出于可理解的原因,它是主要交互的工具)转向assert关闭。

第三,最后,您可以遵循this question中的方法,并暂时取消定义NDEBUG以包括cassert,然后重新定义它。该给您assert(),并在我检查时终止您的会话。不是我用R进行调试的方法,但是如果您真的必须...