我原以为这是一个广泛问的问题,但我还没有找到答案。
我正在调试一些C ++代码,这些代码只是以某些函数句柄作为输入以微妙的方式创建错误。长话短说明了问题,但我在.cpp文件中定义:
#define DEBUG(x) do { std::cerr << x << std::endl; } while (0)
不用说代码充斥着:
DEBUG("Foo's address")
DEBUG(&Foo)
现在我假设在&#34;发布&#34;编译器会忽略所有这些预编译器输出。但它没有!
那么在实践中如何做到这一点(我想留下未来添加的输出,但显然不希望它在发布版本中)?我正在尝试使用cmake的clion,这是IDE /编译器特有的吗?
由于
答案 0 :(得分:2)
根据您的编译器,它可能会定义一些东西,告诉您编译处于调试模式(或者您可以在命令行上自己完成),然后:
#ifndef _DEBUG // works in VS
#define DEBUG(x)
#else
#define DEBUG(x) do { std::cerr << x << std::endl; } while (0)
#endif
有关使用哪个宏的更多讨论,请参阅this问题。
答案 1 :(得分:1)
这样做的便携方法是使用NDEBUG
#ifdef NDEBUG
#define DEBUG(x)
#else
#define DEBUG(x) do { std::cerr << x << std::endl; } while (0)
#endif
答案 2 :(得分:0)
在所谓的&#34;发布版本&#34;中消除日志消息通常是错误的。毕竟,&#34;发布版本&#34;是您最需要记录信息的地方!当最终用户除了&#34;它没有工作&#34; 或&#34; 之外,你甚至希望分析并解决问题。它崩溃了&#34;?
因此,不要消除软件创建的有价值的信息,以帮助您进行错误修正会话,而是考虑如何保存和保存它,以便在出现问题时最终用户可以轻松地将其传输给您。比如,当应用程序在用户的计算机上运行时,将日志消息重定向到日志文件(可能是应用程序本身提供了一个&#34;发送日志文件以支持&#34;功能,或类似的东西)。
代码
DEBUG("Foo's address") DEBUG(&Foo)
应该替换为:
Log("Foo's address");
Log(std::to_string(&Foo));
然后在您的Log
函数内部,可能会有void Log(std::string const& message)
这样的签名,您可以检查DEBUG
宏并采取相应的行动:
void Log(std::string const& message)
{
#ifdef DEBUG
// write message to std::cerr
#else
// write message to log file
#endif
}
现在,当然,DEBUG
不是标准宏(与NDEBUG
不同,后者会打开和关闭assert
)。它没有隐式定义。您必须在调用编译器时自己定义它。例如,/DDEBUG
与MSVC或-DDEBUG
与GCC。有可能你的IDE在运行编译器时添加了这样的标志或类似-D_DEBUG
之类的东西,但是,它仍然不是标准的,也不是编译器本身的一部分。 (实际上,如果您打算像LOG_TO_CONSOLE
那样使用它,您可能会考虑使用宏的不同名称。)
无论如何,这只是为了给你一个做什么的灵感。您可能更喜欢基于std::ostream
的方法,而不是采用std::string
的函数。 Stackoverflow上有很多问题和答案。
重要的一点是:假设您的软件一旦发布就不再需要,请不要丢弃有价值的日志信息。会有错误和模糊的错误描述。