Incorporate diagnostic tests into your program . The using, for example, the assert()
macro is one convenient mechanism for interactive programs.
The assert
macro expands to a void expression:
...
When it is executed, if expression
(which must have a scalar type) is false, the assert
macro writes outputs information about the particular call that failed assertion (including the text of the argument, the name of the source file, the source line number, and the name of the enclosing function) on the standard error stream in an implementation-defined format and calls the abort()
function.
In the following example, the test for integer wrap has been was omitted for the unsigned multiplication based on the assumption that MAX_TABLE_SIZE * sizeof(char *)
cannot exceed SIZE_MAX
. While we know this is true, it cannot do any harm to codify this assumption.
...
Assertions are primarily intended for use during debugging, and are generally turned off before code is shipped by defining NDEBUG
(typically as a flag passed to the compiler). Consequently, assertions are only useful should be used to protect against incorrect assumptions , and are not intended for runtime error checking. Examples of improper assertions include:
Assertions should not be used to check for
- invalid user input
- file not found
- out of memory
- invalid permissions
...
In particular, assertions are generally unsuitable for server programs or embedded systems. A failed assertion could lead to a denial-of-service attack if a hacker discovered malicious user could discover how to trigger it, e.g. such as if size
were in some way derived from client input. In such situations, a soft failure mode such as writing to a log file is more appropriate.
...