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". This is just a convention used by Microsoft Visual Studio for two different default configurations in the IDE. It's not even a Visual C++ thing, it's just in the 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:
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). In a "debug build" configuration, in contrast, NDEBUG is not defined by default for any translation unit.
NDEBUG causes the assert macro to do nothing. assert is a great way to verify certain assumptions about your code. 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.
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. 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.
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. 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. 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. You should not use it to handle errors related to external resources (out of memory, network errors, filesystem errors) or to bad user input.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With