Of course. The point is, if the asserts are disabled for release, then your QA testing (in other words, the real testing) will never hit them, which makes them pointless.
Printable View
Not sure I want you to be in love with me (my wife certainly would get a bit jealous, either way) or some of my current and former collegues [I think some of those are single], but I can assure you that you are not alone.
Where I work, we have a choice "debug" and "always" asserts - obviously, debug asserts are for debug builds (checking for programmer errors, or extra checking that don't actually make things go terribly wrong [just stupid/wrong to do]), whilst always asserts are there all the time, for checking against things that will definitely go wrong, but not necessarily at a point where it can be easily identified.
--
Mats
Requirements of high criticality code (eg developed to SIL 4 - safety critical) would not work well with asserts(). For those types of development it is generally necessary to define requirements (preconditions, postconditions, etc) of code, and then ensure through analysis and design that the code IS NOT invoked in any way that does not meet the requirements. Using a run-time mechanism to detect violated requirements is insufficient to satisfy such demands.
Consider software that monitors human vital signs and controls a respirator: the set of conditions when that software can terminate safely are very small (eg when medical staff consider it appropriate to take the patient off the respirator).
Sure, and asserts that fire regularly even if the code is not safety-critical is still very bad. The point of having an assert is to make the error condition more recognizable. I presume that safety-critical devices also have to ensure that memory violations are not halting the system, for example, and an assert(p != NULL) would not really do here - you need full checking that the pointer is valid before attempting to use it [or make sure pointers are never invalid, which of course is a better approach].
--
Mats
In high criticality code, the more usual approach is to ensure pointers are never invalid in the first place. In practice, that means a few constraints (eg dynamic memory allocation is rarely used in a high critical application, except in a clearly defined startup or initialisation phase, reinitialisation virtually never occurs, etc) as that makes it easier to analyse the code and gather evidence that unwanted behaviours do not occur (or are acceptably unlikely to occur).
Clearly that requires a lot more analysis (both of functions, and how the system as a whole uses them). But a side-effect is that assertions are generally unneeded: the system design prevents low level assertions from failing anyway.