简体   繁体   English

什么是“调试断言失败”

[英]what is “debug assertion failed”

The same source code, compiled into debug version will throw "debug assertion failed" . 编译为调试版本的相同源代码将引发“调试断言失败” But when compiled into release version, it can be executed normally. 但是当编译为发行版时,它可以正常执行。

So who can explain in detail what is the meaning of "debug assertion failed" ? 那么谁能详细解释“调试断言失败”是什么意思呢?

I am quite sure there is something wrong within the source code. 我很确定源代码中有问题。 But why it can be executed normally when compiled into release version? 但是,为什么将其编译为发行版后可以正常执行?

C++ has no notion of "debug builds" and "release builds". C ++没有“调试版本”和“发行版本”的概念。 This is just a convention used by Microsoft Visual Studio for two different default configurations in the IDE. 这只是Microsoft Visual Studio在IDE中用于两个不同默认配置的约定 It's not even a Visual C++ thing, it's just in the IDE. 它甚至不是Visual C ++,而是在IDE中。

It is important to understand how those Visual Studio features interact with the standard C++ features assert and NDEBUG , so let me try to explain that: 了解这些Visual Studio功能与标准C ++功能assertNDEBUG交互方式非常重要,因此让我尝试解释一下:


One aspect of a Visual Studio "release build" configuration is that the NDEBUG preprocessor macro is defined by default for all translation units (which more or less means "for all .cpp files" in this case). Visual Studio“发布版本”配置的一个方面是,默认情况下为所有翻译单元定义NDEBUG预处理程序宏(在这种情况下,或多或少意味着“对于所有.cpp文件” )。 In a "debug build" configuration, in contrast, NDEBUG is not defined by default for any translation unit. 相反,在“调试构建”配置中,默认情况下未为任何翻译单元定义NDEBUG

NDEBUG causes the assert macro to do nothing. NDEBUG使assert宏不执行任何操作。 assert is a great way to verify certain assumptions about your code. assert是验证有关代码的某些假设的好方法。 As the name of the macro says, you use it to assert preconditions, postconditions and invariants; 就像宏的名称所说的那样,您可以使用它来声明前置条件,后置条件和不变式。 things that you believe your code does correctly. 您认为代码可以正确执行的操作。

If an assertion fails, then you have discovered a bug. 如果断言失败,则说明您发现了一个错误。 Your code does not do what you thought it did. 您的代码没有执行您认为的操作。 This is a very serious problem and usually warrants immediate termination of the application process to prevent further problems. 这是一个非常严重的问题,通常需要立即终止申请过程以防止进一步的问题。

Another aspect of a "debug build" configuration in Visual Studio is that it alters the way the application terminates when an assertion has failed, reporting bugs by showing you a "debug assertion failed" message box. Visual Studio中“调试构建”配置的另一个方面是,它更改了断言失败时应用程序终止的方式,并通过向您显示“调试断言失败”消息框来报告错误。


I am quite sure there is something wrong within the source code. 我很确定源代码中有问题。 But why it can be executed normally when compiled into release version? 但是,为什么将其编译为发行版后可以正常执行?

You probably did not use assert in your own code but are using code from some library (perhaps the standard library?) which contains assertions. 您可能未在自己的代码中使用assert ,而是使用某个包含断言的库(也许是标准库?)中的代码。 For example, an assertion which makes sure that a function is called with correct arguments. 例如,一个断言可确保使用正确的参数调用函数。 Look at what the error message box says exactly; 查看错误消息框确切说明的内容; it will give you a hint. 它会给你一个提示。

That your program keeps running despite of an error is a bad thing. 即使有错误,您的程序仍然可以运行是一件坏事。 It likely exhibits undefined behaviour, and the fact that you didn't notice it doing strange things should be considered bad luck, because with undefined behaviour, anything can happen at any time. 它可能表现出不确定的行为,您没有注意到它在做奇怪的事情这一事实应该被认为是倒霉的,因为使用不确定的行为,任何时候都可能发生任何事情。 Running normally by sheer coincidence just hides an error which will hit you at a later point in the future. 完全出于巧合而正常运行只会隐藏一个错误,将来您会遇到这种错误。


The logic behind the "debug build" and "release build" configurations in Visual Studio is that you find all bugs during development, testing the "debug build", whereas the "release build" run by your users has no more bug detection in it, because detecting the bugs may slow down the program. Visual Studio中“调试版本”和“发布版本”配置背后的逻辑是,您在开发过程中发现了所有错误,并测试了“调试版本”,而用户运行的“发布版本”中没有更多的错误检测功能。 ,因为检测到错误可能会使程序变慢。

Personally, I consider this logic to be deeply flawed. 我个人认为这种逻辑存在严重缺陷。 Consider not defining NDEBUG anywhere by default, and enable it only in those translation units where performance actually suffers. 考虑默认情况下不要在任何地方定义NDEBUG ,并且在性能确实受到影响的那些翻译单元中启用它。 Continuing program execution even if you know that the program is not what you believed it was can be dangerous because the application logic becomes undefined. 即使您知道程序不是您认为的那样,继续执行程序也是很危险的,因为应用程序逻辑变得不确定。 assert is designed specifically so that you turn it on or off for individual files. assert是专门设计的,因此您可以为单个文件打开或关闭它。 Unfortunately, this feature is not used much, which effectively turns off a valuable error detection mechanism in many programs. 不幸的是,此功能使用不多,有效地关闭了许多程序中有价值的错误检测机制。


One last word: assert should only be used to detect bugs. 最后一句话: assert应该仅用于检测错误。 You should not use it to handle errors related to external resources (out of memory, network errors, filesystem errors) or to bad user input. 您不应使用它来处理与外部资源有关的错误(内存不足,网络错误,文件系统错误)或用户输入错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM