Assertion (computing)
|
In computer programming, an assertion is a programming language construct that checks whether an expression is true. Assertions are written so that they should always evaluate to true. If an assertion is false, it indicates a possible bug in the program. This is called an "assertion failure."
Programmers add assertions to the source code as part of the development process. They are intended to simplify debugging and to make potential errors easier to find. Since an assertion failure often indicates a bug, many assertion implementations will print additional information about the source of the problem (such as the filename and line number in the source code or a stack trace). Most implementations will also halt the program's execution immediately.
Contents |
Usage
The purpose of an assertion is to verify that an assumption made by the programmer during the implementation of the program remains valid when the program is executed. For example, consider the following Java code:
int total = countNumberOfUsers(); if (total % 2 == 0) { // total is even } else { // total is odd assert(total % 2 == 1); }
In Java, %
is the remainder operator (not modulus) — if its first operand is negative, the result can also be negative. Here, the programmer has assumed that total
is non-negative, so that the remainder of a division with 2 will always be 0 or 1. The assertion makes this assumption explicit — if countNumberOfUsers
does return a negative value, it is likely a bug in the program.
Assertions can also be a form of documentation: they can describe the state the code expects to find before it runs (its preconditions), and the state the code expects to result in when it is finished running (postconditions). The advantage of using assertions rather than comments is that assertions are checked for validity every time the program is run; if the assertion no longer holds, the programmer will be notified. This prevents the code from getting out of sync with the assertions (a problem that can occur with comments).
During the development cycle, the programmer will typically run the program with assertions enabled. When an assertion failure occurs, the programmer is immediately notified of the problem. Many assertion implementations will also halt the program's execution — this is useful, since if the program continued to run after an assertion violation occurred, it might corrupt its state and make the cause of the problem more difficult to locate. Using the information provided by the assertion failure (such as the location of the failure and perhaps a stack trace), the programmer can usually fix the problem. Thus, assertions can simplify debugging.
Assertions are also sometimes placed at points the execution is not supposed to reach. For example, assertions could be placed at the default
clause of the switch
statement in languages such as C, C++, and Java; cases that are intentionally not handled by the programmer will raise an error and abort the program rather than silently continuing in an erroneous state.
Disabling assertions
Assertions can be enabled or disabled, usually on a program-wide basis. If assertions are disabled, assertion failures are ignored. Since assertions are primarily a development tool, they are often disabled when the program is released. Because some versions of the program will include assertions and some will not, it is essential that the presence of assertions does not change the meaning of the program. In other words, assertions ought to be free of side effects.
The removal of assertions from production code is almost always done automatically. It usually is done via conditional compilation, for example by using the preprocessor in C or C++ or by passing an option to the runtime engine, as in Java. Some people, however, object to the removal of assertions by citing an analogy that the execution with assertion in development stage and without it in practice is like practicing swimming in a pool with a lifeguard and then going swimming in the sea without a lifeguard. They add assertions also could help make the program fail-safe.
Comparison with error handling
It is worth distinguishing assertions from routine error handling. Assertions should be used to document logically impossible situations — if the "impossible" occurs, then something fundamental is clearly wrong. This is distinct from error handling: most error conditions are possible, although some may be extremely unlikely to occur in practice. Using assertions as a general-purpose error handling mechanism is usually unwise: assertions do not allow for graceful recovery from errors, and an assertion failure will often halt the program's execution abruptly. Assertions also do not display a user-friendly error message.
Consider the following example of using an assertion to handle an error:
int *ptr = malloc(sizeof(int) * 10); assert(ptr != NULL); // use ptr
Here, the programmer is aware that malloc
may return a NULL
pointer if memory could not be allocated. This is possible: the operating system does not guarantee that every call to malloc
will succeed, and the program should be prepared to handle the failure. An assertion is probably not the best choice here, because a malloc failure is not logically impossible — it is a legitimate possibility, albeit not one that will arise very often in practice. The assertion in this example does serve one useful purpose, however: it documents that the programmer has deliberately decided not to provide robust error handling for memory allocation failures.
See also
External links
- Java
- Programming With Assertions (http://java.sun.com/j2se/1.4.2/docs/guide/lang/assert.html)
- Technical Article "Using Assertions (http://java.sun.com/developer/JDCTechTips/2002/tt0409.html)"
- Citations from CiteSeer (http://citeseer.org/cs?q=assertion)de:Assertion