C. Michael Pilato wrote:
> What are the differences between these two approaches? You noted
> "possible data loss". How so?
"assert(condition)" checks "condition" and aborts with a useful message - but
only if the software is compiled in "debug" mode (usually by setting a
preprocessor symbol "DEBUG" or "_DEBUG", or by not setting "NDEBUG"). When the
software is compiled in "release" mode, the "assert" macro expands to nothing,
so the condition is not even evaluated or tested.
"if (!condition) abort();" checks the condition, and aborts if it is false,
regardless of whether it is a debug build or a release build.
Therefore "assert" is generally appropriate for checking conditions which,
according to the design of the software, can never occur. Such conditions only
occur when there is a bug in the software, and thus help to find the bug. If
such a bug affects the user of a release build, the software will not abort at
that point but will continue and have undefined behaviour. Hopefully it will
soon abort due to dereferencing an invalid pointer, or will produce the wrong
result and the user will notice and report a bug, or maybe it will go on to
produce the right result for the wrong reasons, and the user will not notice.
"assert" should never be used for checking conditions that can arise from
invalid inputs, because such errors should be handled gracefully in release
builds as well as debug builds. "assert" is a debugging aid, not an error
handler, and certainly does not lead to a graceful exit.
(Sometimes it can be difficult to decide whether a condition is to be regarded
as "invalid input" - e.g. if the program writes to a private file and then
reads back from it, should the data read back be considered as "input" or as
internal data that the program is managing for itself?)
"abort" can be useful if there is a condition that can only be due to a bug,
but the programmer feels that in this case ignoring the condition might lead to
data loss, and aborting would not. I would still recommend using something
else that causes a more informative exit than "abort" does.
In the book "Writing Solid Code" by Steve Maguire, the chapter "Assert
Yourself" makes these points:
* Maintain both ship and debug versions.
* Use assertions to validate function arguments, and document unclear ones.
* Remove undefined behaviour, or catch attempts to make use of it.
* Assertions are not for detecting error conditions.
* Remove or assert implicit assumptions.
* Assertions are forever.
That last point means that whereas you might insert "printf" and other
debugging aids temporarily and then remove them, your assertions should stay in
the code forever, like regression tests. In their most typical use at the
beginning of a function, they should be concise enforcements of the API.
To unsubscribe, e-mail: email@example.com
For additional commands, e-mail: firstname.lastname@example.org
Received on Tue Nov 9 17:47:53 2004