什么是“调试断言失败”

时间:2017-03-19 08:25:13

标签: c++ visual-studio-2015

编译为 debug 版本的相同源代码将抛出“debug assertion failed”。但是当编译成发布版本时,它可以正常执行。

那么谁能详细解释“调试断言失败”的含义是什么?

我很确定源代码中有问题。但是为什么在编译成发布版本时可以正常执行?

1 个答案:

答案 0 :(得分:4)

C ++没有“debug builds”和“release builds”的概念。这只是Microsoft Visual Studio 使用的约定,适用于IDE中的两种不同默认配置。它甚至不是Visual C ++的东西,只是在IDE中。

了解这些Visual Studio功能如何与标准C ++功能assertNDEBUG进行交互非常重要,所以让我试着解释一下:

Visual Studio“发布版本”配置的一个方面是默认情况下为所有翻译单元定义NDEBUG预处理器宏(对于所有.cpp文件,这或多或少意味着在这种情况下)。相反,在“调试版本”配置中,默认情况下不会为任何翻译单元定义NDEBUG

NDEBUG会导致assert宏无效。 assert是验证有关代码的某些假设的好方法。正如宏的名称所说,你用它来断言先决条件,后置条件和不变量;你相信你的代码正确的事情。

如果断言失败,那么您发现了一个错误。 您的代码没有按照您的想法执行。这是一个非常严重的问题,通常需要立即终止申请流程以防止出现其他问题。

Visual Studio中“调试构建”配置的另一个方面是它改变了断言失败时应用程序终止的方式,通过向您显示“调试断言失败”消息框来报告错误。

  

我很确定源代码中有问题。但是为什么在编译成发行版时可以正常执行?

您可能没有在自己的代码中使用assert,而是使用包含断言的某些库(可能是标准库?)中的代码。例如,一个断言,确保使用正确的参数调用函数。查看错误消息框准确说明的内容;它会给你一个提示。

尽管出现错误,你的程序仍在运行是一件坏事。它可能表现出未定义的行为,并且你没有注意到它做了一些奇怪的事情应该被认为是运气不好,因为在未定义的行为中,任何事情都可能随时发生。通过纯粹的巧合正常运行只会隐藏一个错误,这将在以后的某个时刻点击你。

Visual Studio中“调试构建”和“发布版本”配置背后的逻辑是,您在开发过程中发现所有错误,测试“调试版本”,而您的用户运行的“版本构建”不再有bug在其中检测,因为检测到错误可能会减慢程序。

就个人而言,我认为这种逻辑存在严重缺陷。考虑默认情况下不在任何地方定义NDEBUG,并在性能实际受到影响的那些翻译单元中仅启用 。即使您知道程序不是您认为的程序,也会继续执行程序,这可能很危险,因为应用程序逻辑变得不明确。 assert专门设计,以便您为单个文件打开或关闭它。不幸的是,这个功能使用不多,在许多程序中有效地关闭了一个有价值的错误检测机制。

最后一句话:assert应仅用于检测错误。您不应该使用它来处理与外部资源(内存不足,网络错误,文件系统错误)或用户输入错误相关的错误。