如果已定义,则使用#(_DEBUG)

Use of #if defined(_DEBUG)

本文关键字:DEBUG 定义 如果      更新时间:2023-10-16

我正在编写一个基于C++MFC的应用程序。偶尔我会添加#if defined(_DEBUG)语句,以便在开发过程中对我有所帮助。我的经理要求我删除所有这样的语句,因为他不想要两个版本的代码。我的感觉是,如果没有使用#if defined(_DEBUG)的能力,漏洞更有可能在开发过程中悄悄出现而未被发现。

其他人对此有什么想法吗?

好吧,运行库和MFC有两个版本,调试和发布,所以总是有两个代码版本。

使用#ifdef(_DEBUG)和assert()将在调试过程中帮助您。

但是。。。

不建议在#ifdef子句中添加类/结构成员,因为对象的二进制接口将不同,如果从调试和发布版本序列化或发送这样的结构,它们将不同。

E.G:

#include <assert.h>
class MyClass
{
    void SetA(int a)
    {
        assert(a<10000); // this is recommended
    }
#ifdef _DEBUG
    int m_debugCounter; // This is not recommended
#endif
};

在本例中,sizeof(MyClass)与调试和发布版本不同。

使用生产代码编译调试代码有优缺点。

一些优点:

  • 生产可执行文件将更小
  • 准备从未使用过的日志消息、统计信息等时不会浪费资源
  • 如果外部库仅由调试代码使用,则可以删除它们的依赖项

一些缺点:

  • 您最终会得到两个不同的可执行文件
  • 由于某些调试日志在生产版本中不可用,这使得现场故障排除更加困难
  • 存在两个版本的行为不相同的风险。例如,错误可能出现在生产版本中,但在测试过程中没有出现,因为测试是在调试版本中完成的
  • 两个版本之间存在不兼容的风险,例如文件格式略有不同(如Erab的回答所示)

特别是,如果使用编译出来的代码(甚至是assert()调用),请非常小心,调试代码没有副作用。否则,当调试打开时,您将创建消失的错误。

通过使用一个不错的日志框架,您至少可以获得一些优势。例如,我在使用rLog方面取得了一些成功——我喜欢它的一点是它经过了优化,可以最大限度地减少休眠日志记录语句的开销。其他最新的日志记录框架也提供了类似的功能。

话虽如此,我使用过的每个C++环境都至少有一定级别的编译入/编译出调试代码。例如,assert()是根据NDEBUG宏编译的。ASSERT()/DEBUG似乎是MSVC在该主题上的一个特定变体(尽管据我所知,MSVC也支持更标准的ASSERT()/NEDEBUG)。

如果经理想要这样,他不理解目标代码质量。。。如果#If应该删除,您也可以删除任何类型的资产。因为他们只是隐藏#if_DEBUG。请记住,MFC和CRT本身充满了这个(真正的)有用的#if_DEBUG代码!

如果没有这样特殊的_DEBUG块,我就无法针对类的滥用,也无法捕获内部问题。