0

我正在编写一个程序,我想根据各种宏变量的值输出不同类型的调试信息(这样我就可以更改一个标志的值,然后导致不同级别的信息写入屏幕)。

例如,假设我有以下代码将有关我的程序的信息打印到屏幕上(称为D1):

cout << "% Percentage complete: "
     << ceil((static_cast<double>(idx)/static_cast<double>(ITERATIONS))*(100.00))
     << "%" << endl;
cout << "x = [ x; ";
for(int i=0; i<space.getDimension(); i++)
    cout << visited.vec[visited.bestIndex].x[i] << "\t";
cout << "];" << endl;

现在,还假设我有以下代码可以在屏幕上打印有关我的程序的不同信息(称为D2):

cout << "best = [ best; "
     << visited.vec[visited.bestIndex].meanQALY() << "];\n" << endl;
space.displayConstraintsMATLAB(idx+1);

我希望能够在我的代码中的某些位置插入诸如#D1#D2之类的语句,并让宏处理器用上面的代码块替换这些语句。

我怎样才能做到这一点?

(如果宏不是理想的解决方案,我很高兴听到有关不同方法的建议。)

4

2 回答 2

1

您可以制作一个为您进行调试的宏 - 例如:

#ifdef D1
#    define DEBUG(var) //Debug 1 print implementation here
#elif defined D2
#    define DEBUG(var) //Debug 2 print implementation here
#else
#    define DEBUG(var) //No-op
#endif

否则,您可以创建一个调试函数,然后在该函数内部对语句进行类似的检查,#if def以查看您希望如何处理输入。该功能版本具有更早的类型检测,因此当您尝试打印不可处理的内容(某些自定义对象)时,它往往会以更好的方式告诉您错误。此外,如果函数是无操作(在发布模式下没有内部),那么当存在任何优化标志时,编译器将丢弃函数调用,因此您不会在发布模式下支付任何额外费用调试调用。

对于我自己的调试调用,我通常定义一个流运算符,很像 std::cout,将所有输入转换为字符串或 char*,然后如果定义了 DEBUG 或不打印任何内容,则将它们放入调试函数中。对于异常和日志记录,您可以执行具有不同严重性级别(信息、警告、错误等)的类似指标。这使得在 C++ 中抛出调试代码变得像在更现代的语言 imo 中一样容易。

于 2012-08-10T16:55:27.593 回答
1

在我看来,您正在寻找的是一个日志记录工具。查看此线程以获取一些建议

为什么使用整个框架而不是宏?

问题是正确的日志记录比看起来更困难。有线程问题、会话、类和对象实例是您必须考虑的因素。日志文件缓冲、翻转和压缩日志文件也是您必须考虑的问题。您可能还想通过网络或系统日志(或两者)或数据库登录。自己正确地实现所有这些需要做很多工作。

宏好用吗?

当然!在我们的项目中,我们定义了一个名为 LOG 的宏,它包装了对我们的日志框架的调用(我们正在使用log4cpp)。如果有一天我们打算迁移到另一个框架,我们只需要在一个地方重新定义我们的 LOG 宏,而不是梳理整个代码库。这是因为大多数日志框架共享一个类似的接口,通常由日志级别和消息字符串组成。

于 2012-08-10T17:32:12.530 回答