C++ “什么是”呢;“调试断言失败”;

C++ “什么是”呢;“调试断言失败”;,c++,visual-studio-2015,C++,Visual Studio 2015,编译到debug版本的相同源代码将抛出“debug assertion failed”。但是当编译成发布版时,它可以正常执行 那么,谁能详细解释“调试断言失败”的含义呢 我很确定源代码中有错误。但是为什么编译成发布版时可以正常执行呢?C++没有“调试版本”和“发布版本”的概念。这只是Microsoft Visual Studio对IDE中两种不同的默认配置使用的一种约定。它甚至不是一个VisualC++的东西,它只是在IDE中。 P>重要的是了解这些VisualStudio的特性是如何与标准的

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

那么,谁能详细解释“调试断言失败”的含义呢

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

C++没有“调试版本”和“发布版本”的概念。这只是Microsoft Visual Studio对IDE中两种不同的默认配置使用的一种约定。它甚至不是一个VisualC++的东西,它只是在IDE中。 <> P>重要的是了解这些VisualStudio的特性是如何与标准的C++特性和<代码> NDECHGE/CODE>交互的,所以让我来解释一下:


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

NDEBUG
导致
assert
宏不执行任何操作<代码>断言是验证代码的某些假设的一种很好的方法。正如宏的名称所说,您可以使用它来断言前置条件、后置条件和不变量;您认为代码正确执行的操作

如果断言失败,那么您发现了一个bug您的代码没有达到您认为的效果。这是一个非常严重的问题,通常会保证立即终止应用程序进程,以防止出现进一步的问题

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


我很确定源代码中有错误。但为什么编译成发行版后可以正常执行呢

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

即使出现错误,您的程序仍继续运行是一件坏事。它可能表现出未定义的行为,而你没有注意到它做奇怪的事情这一事实应该被认为是运气不好,因为有了未定义的行为,任何事情都可能随时发生。正常运行完全是巧合,只是隐藏了一个错误,它将在将来的某个时候击中你


Visual Studio中“调试版本”和“发布版本”配置背后的逻辑是,在开发过程中,您可以找到所有的bug,测试“调试版本”,而用户运行的“发布版本”中没有更多的bug检测,因为检测bug可能会降低程序的速度

我个人认为这个逻辑是有缺陷的。默认情况下,不要考虑“代码> NDebug ./COD>任何地方,而只在性能实际受影响的那些翻译单元中启用它。即使您知道程序不是您认为的那样,继续执行程序也可能是危险的,因为应用程序逻辑未定义<代码>断言是专门设计的,可以为单个文件打开或关闭它。不幸的是,这个特性并没有被大量使用,这有效地关闭了许多程序中有价值的错误检测机制



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

这正是调试配置的要点。运行库告诉您有关失败函数的信息,这种故障往往很难诊断。此额外帮助在版本配置中关闭。还有一点你应该自己使用,你的代码很少会有太多的assert()调用<代码>NDEBUG不是特定于Visual Studio的;这是自ISO C 90以来的标准。VisualStudio调试配置在更多方面有所不同,没错,但问题是关于
assert
@MSalters:你是对的。我做了一个编辑来解释这一点。编辑得好。撰写答案的挑战在于广泛的受众;你有绝对的初学者和语言律师;)@马尔特斯:真的!如果没有其他问题,那么回答SO上的问题是一个很好的写作练习:)