2

我只需要在调试模式下让一些代码行“活动”,而在发布模式下被忽略。有没有办法做这样的事情:

#include <iostream>
using namespace std;

#ifdef _TEST_
#define _cerr cerr
#else
#define _cerr // cerr
#endif

int main() {
   _cerr << "TEST message" << endl;
}

因此,当_TEST_未定义时,某些行会被注释或从代码中删除。我知道评论在其余部分之前被处理,所以这段代码是错误的。但是,如果不明确使用#ifdefs,我怎样才能获得我需要的行为呢?

4

10 回答 10

9

您可以为此使用宏:

#ifdef _TEST_
#define DEBUG_ONLY(x) x;
#else
#define DEBUG_ONLY(x)
#endif

int main() {
    DEBUG_ONLY(cerr << "TEST message" << endl)
}
于 2009-11-03T12:42:45.960 回答
5

如果您所追求的是在发布版本中删除的调试日志记录,您可以执行以下操作:

#ifdef _TEST_
#define LOG(x) (cerr << x << endl)
#else
#define LOG(x)
#endif

...

int main() {
    LOG("TEST message");
}
于 2009-11-03T12:48:05.777 回答
4

用这个:

#ifdef _TEST_
#define DEBUG_TEST(x) x
#else
#define DEBUG_TEST(x)
#endif

int main() {
    DEBUG_TEST(_cerr << "TEST message" << endl);
}
于 2009-11-03T12:43:14.367 回答
2

ifdefs 是要走的路。你怎么知道编译器是否处于发布与调试模式?除了在预处理阶段之外,还会在什么时候进行沟通?在其他什么阶段您可以决定删除/添加代码(除了在模板生成期间)。嘿,也许我们可以使用模板生成...但是您仍然必须以某种方式关闭 ifdef 以控制您的模板。

也许有一种我没有想到的非常巧妙的方法来做到这一点,但每个人都知道/为此目的使用 ifdefs。如果你扔给他们一个曲线球,它只会大大增加维护代码的人力成本。

坚持使用 ifdef。

于 2009-11-03T12:41:55.760 回答
1

这基本上可以满足您的要求:

#ifdef _TEST_
#define _cerr  cerr
#else
#define _cerr  if (1) {} else cerr
#endif

else但是,例如,如果您编写如下代码会收到关于歧义的编译器警告,请不要感到惊讶:

if (something)
  _cerr << "Why?" << std::endl;

您应该始终意识到这实际上_cerr是一个重要的宏。

于 2009-11-03T12:47:26.693 回答
1

将 _cerr 定义为 nothing 将使编译失败。您可以改为定义一个在发布模式下排除的宏。

例如:

#ifdef _TEST_
#define LOG_ERROR(log) cerr << log << endl;
#else
#define LOG_ERROR(log) 
#endif

然后在您的代码中:

int main() {
   LOG_ERROR("TEST message");
}
于 2009-11-03T12:47:54.013 回答
0

创建您自己的 NULL 流。

#include <iostream>

class NullStream    {};
template<typename T>
NullStream& operator <<(NullStream& n,T const& data)                        {return n;}
NullStream& operator <<(NullStream& n,std::ostream& (*)(std::ostream&))     {return n;}

#ifdef  _TEST_
#define myerr       std::cerr
#else
NullStream  myerrstream;
#define myerr       myerrstream
#endif

int main()
{
    myerr << "Hi" << std::endl;;
    myerr << std::endl;;
}
于 2009-11-03T17:35:11.563 回答
0
int main() {
#ifdef _TEST_
   _cerr << "TEST message" << endl;
#endif
}
于 2009-11-03T12:43:02.100 回答
0

不,绝对,不。

尝试对此进行变体:

#ifdef _TEST_
    ostream& _cerr = cerr;
#else
    ostringstream _cerr;
#endif

(基本上你会想要一个只丢弃其输入的流。)

于 2009-11-03T12:43:19.790 回答
0

“无登录版本”的更好解决方案是以下类:

class NullStream {
   template<typename T> NullStream& operator<< const(T&) { }
};

利用:

#ifdef DEBUG
#define CERR std::cerr
#else
#define CERR NullStream()
#endif
于 2009-11-03T13:44:31.030 回答