Assertion (computing)
Encyclopedia
In computer programming
, an assertion is a predicate
(for example a true–false statement) placed in a program to indicate that the developer thinks that the predicate is always true at that place.
For example, the following code contains two assertions:
Programmers can use assertions to help specify programs and to reason about program correctness. For example, a precondition
— an assertion placed at the beginning of a section of code — determines the set of states under which the programmer expects the code to execute. A postcondition
— placed at the end — describes the expected state at the end of execution.
The example above uses the notation for including assertions used by C.A.R. Hoare in his 1969 paper. That notation cannot be used in existing mainstream programming languages. However, programmers can include unchecked assertions using the comment feature
of their programming language. For example, in C
:
The braces included in the comment help distinguish this use of a comment from other uses.
Several modern programming languages include checked assertions - statements
that are checked at runtime or sometimes statically. If an assertion evaluates to false at run-time, an assertion failure results, which typically causes execution to abort. This draws attention to the location at which the logical inconsistency is detected and can be preferable to the behaviour that would otherwise result.
The use of assertions helps the programmer design, develop, and reason about a program.
, assertions form part of the design process, and in others, such as C
and Java
, they are used only to check assumptions at runtime. In both cases, they can be checked for validity at runtime but can usually also be suppressed.
s), and the state the code expects to result in when it is finished running (postcondition
s); they can also specify invariant
s of a class
. Eiffel
integrates such assertions into the language and automatically extracts them to document the class. This forms an important part of the method of design by contract
.
This approach is also useful in languages that do not explicitly support it: the advantage of using assertion statements rather than assertions in comment
s is that the program can check the assertions every time it runs; if the assertion no longer holds, an error can be reported. This prevents the code from getting out of sync with the assertions (a problem that can occur with comments).
code:
In Java
,
A major advantage of this technique is that when an error does occur it is detected immediately and directly, rather than later through its often obscure side-effects. Since an assertion failure usually reports the code location, one can often pin-point the error without further debugging.
Assertions are also sometimes placed at points the execution is not supposed to reach. For example, assertions could be placed at the
, C++
, and Java
. Any case which the programmer does not handle intentionally will raise an error and the program will abort rather than silently continuing in an erroneous state.
In Java
, assertions have been a part of the language since version 1.4. Assertion failures result in raising an
, they are added on by the standard header
the header
libraries still have the
The danger of assertions is that they may cause side effects either by changing memory data or by changing thread timing. Assertions should be implemented carefully so they cause no side effects on program code.
Assertion constructs in a language allow for easy test-driven development
(TDD) without the use of a third-party library.
, or even the full program state if the environment supports core dump
s or if the program is running in a debugger
), the programmer can usually fix the problem. Thus assertions provide a very powerful tool in debugging.
Static assertions are particularly useful in compile time template metaprogramming
, but can also be used in low-level languages in C by introducing illegal code if (and only if) the assertion fails. For example, in C a static assertion can be implemented like this:
If the
Another popular way of implementing assertions in C is:
If the
Both of these methods require a method of constructing unique names. Modern compilers support a __COUNTER__ preprocessor define that facilitates the construction of unique names, by returning monotonically increasing numbers for each compilation unit.
Some languages, including C/C++, completely remove assertions at compile time using the preprocessor
. Java requires an option to be passed to the run-time engine in order to enable assertions. Absent the option, assertions are bypassed, but they always remain in the code unless optimised away by a JIT compiler at run-time or excluded by an if(false) condition at compile time, thus they need not have a run-time space or time cost in Java either.
Programmers can always build checks into their code that are always active by bypassing or manipulating the language's normal assertion-checking mechanisms.
Consider the following example of using an assertion to handle an error:
Here, the programmer is aware that
Computer programming
Computer programming is the process of designing, writing, testing, debugging, and maintaining the source code of computer programs. This source code is written in one or more programming languages. The purpose of programming is to create a program that performs specific operations or exhibits a...
, an assertion is a predicate
First-order logic
First-order logic is a formal logical system used in mathematics, philosophy, linguistics, and computer science. It goes by many names, including: first-order predicate calculus, the lower predicate calculus, quantification theory, and predicate logic...
(for example a true–false statement) placed in a program to indicate that the developer thinks that the predicate is always true at that place.
For example, the following code contains two assertions:
x > 0
and x > 1
, and they are indeed true at the indicated points during execution.Programmers can use assertions to help specify programs and to reason about program correctness. For example, a precondition
Precondition
In computer programming, a precondition is a condition or predicate that must always be true just prior to the execution of some section of code or before an operation in a formal specification....
— an assertion placed at the beginning of a section of code — determines the set of states under which the programmer expects the code to execute. A postcondition
Postcondition
In computer programming, a postcondition is a condition or predicate that must always be true just after the execution of some section of code or after an operation in a formal specification. Postconditions are sometimes tested using assertions within the code itself...
— placed at the end — describes the expected state at the end of execution.
The example above uses the notation for including assertions used by C.A.R. Hoare in his 1969 paper. That notation cannot be used in existing mainstream programming languages. However, programmers can include unchecked assertions using the comment feature
Comment (computer programming)
In computer programming, a comment is a programming language construct used to embed programmer-readable annotations in the source code of a computer program. Those annotations are potentially significant to programmers but typically ignorable to compilers and interpreters. Comments are usually...
of their programming language. For example, in C
C (programming language)
C is a general-purpose computer programming language developed between 1969 and 1973 by Dennis Ritchie at the Bell Telephone Laboratories for use with the Unix operating system....
:
The braces included in the comment help distinguish this use of a comment from other uses.
Several modern programming languages include checked assertions - statements
Statement (programming)
In computer programming a statement can be thought of as the smallest standalone element of an imperative programming language. A program written in such a language is formed by a sequence of one or more statements. A statement will have internal components .Many languages In computer programming...
that are checked at runtime or sometimes statically. If an assertion evaluates to false at run-time, an assertion failure results, which typically causes execution to abort. This draws attention to the location at which the logical inconsistency is detected and can be preferable to the behaviour that would otherwise result.
The use of assertions helps the programmer design, develop, and reason about a program.
Usage
In languages such as EiffelEiffel (programming language)
Eiffel is an ISO-standardized, object-oriented programming language designed by Bertrand Meyer and Eiffel Software. The design of the language is closely connected with the Eiffel programming method...
, assertions form part of the design process, and in others, such as C
C (programming language)
C is a general-purpose computer programming language developed between 1969 and 1973 by Dennis Ritchie at the Bell Telephone Laboratories for use with the Unix operating system....
and Java
Java (programming language)
Java is a programming language originally developed by James Gosling at Sun Microsystems and released in 1995 as a core component of Sun Microsystems' Java platform. The language derives much of its syntax from C and C++ but has a simpler object model and fewer low-level facilities...
, they are used only to check assumptions at runtime. In both cases, they can be checked for validity at runtime but can usually also be suppressed.
Assertions in design by contract
Assertions can function as a form of documentation: they can describe the state the code expects to find before it runs (its preconditionPrecondition
In computer programming, a precondition is a condition or predicate that must always be true just prior to the execution of some section of code or before an operation in a formal specification....
s), and the state the code expects to result in when it is finished running (postcondition
Postcondition
In computer programming, a postcondition is a condition or predicate that must always be true just after the execution of some section of code or after an operation in a formal specification. Postconditions are sometimes tested using assertions within the code itself...
s); they can also specify invariant
Invariant (computer science)
In computer science, a predicate is called an invariant to a sequence of operations provided that: if the predicate is true before starting the sequence, then it is true at the end of the sequence.-Use:...
s of a class
Class (computer science)
In object-oriented programming, a class is a construct that is used as a blueprint to create instances of itself – referred to as class instances, class objects, instance objects or simply objects. A class defines constituent members which enable these class instances to have state and behavior...
. Eiffel
Eiffel (programming language)
Eiffel is an ISO-standardized, object-oriented programming language designed by Bertrand Meyer and Eiffel Software. The design of the language is closely connected with the Eiffel programming method...
integrates such assertions into the language and automatically extracts them to document the class. This forms an important part of the method of design by contract
Design by contract
Design by contract , also known as programming by contract and design-by-contract programming, is an approach to designing computer software...
.
This approach is also useful in languages that do not explicitly support it: the advantage of using assertion statements rather than assertions in comment
Comment (computer programming)
In computer programming, a comment is a programming language construct used to embed programmer-readable annotations in the source code of a computer program. Those annotations are potentially significant to programmers but typically ignorable to compilers and interpreters. Comments are usually...
s is that the program can check the assertions every time it runs; if the assertion no longer holds, an error can be reported. This prevents the code from getting out of sync with the assertions (a problem that can occur with comments).
Assertions for run-time checking
An assertion may be used 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 JavaJava (programming language)
Java is a programming language originally developed by James Gosling at Sun Microsystems and released in 1995 as a core component of Sun Microsystems' Java platform. The language derives much of its syntax from C and C++ but has a simpler object model and fewer low-level facilities...
code:
In Java
Java (programming language)
Java is a programming language originally developed by James Gosling at Sun Microsystems and released in 1995 as a core component of Sun Microsystems' Java platform. The language derives much of its syntax from C and C++ but has a simpler object model and fewer low-level facilities...
,
%
is the remainder operator (or 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, the program may have a bug.A major advantage of this technique is that when an error does occur it is detected immediately and directly, rather than later through its often obscure side-effects. Since an assertion failure usually reports the code location, one can often pin-point the error without further 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 CC (programming language)
C is a general-purpose computer programming language developed between 1969 and 1973 by Dennis Ritchie at the Bell Telephone Laboratories for use with the Unix operating system....
, C++
C++
C++ is a statically typed, free-form, multi-paradigm, compiled, general-purpose programming language. It is regarded as an intermediate-level language, as it comprises a combination of both high-level and low-level language features. It was developed by Bjarne Stroustrup starting in 1979 at Bell...
, and Java
Java (programming language)
Java is a programming language originally developed by James Gosling at Sun Microsystems and released in 1995 as a core component of Sun Microsystems' Java platform. The language derives much of its syntax from C and C++ but has a simpler object model and fewer low-level facilities...
. Any case which the programmer does not handle intentionally will raise an error and the program will abort rather than silently continuing in an erroneous state.
In Java
Java (programming language)
Java is a programming language originally developed by James Gosling at Sun Microsystems and released in 1995 as a core component of Sun Microsystems' Java platform. The language derives much of its syntax from C and C++ but has a simpler object model and fewer low-level facilities...
, assertions have been a part of the language since version 1.4. Assertion failures result in raising an
AssertionError
when the program is run with the appropriate flags, without which the assert statements are ignored. In CC (programming language)
C is a general-purpose computer programming language developed between 1969 and 1973 by Dennis Ritchie at the Bell Telephone Laboratories for use with the Unix operating system....
, they are added on by the standard header
assert.hAssert.hassert.h is a header file in the standard library of the C programming language that defines the C preprocessor macro assert. The macro implements an assertion, which can be used to verify assumptions made by the program and print a diagnostic message if this assumption is false...
defining assert (assertion)
as a macro that signals an error in the case of failure, usually terminating the program. In standard C++C++
C++ is a statically typed, free-form, multi-paradigm, compiled, general-purpose programming language. It is regarded as an intermediate-level language, as it comprises a combination of both high-level and low-level language features. It was developed by Bjarne Stroustrup starting in 1979 at Bell...
the header
cassert
is required instead. However, some C++C++
C++ is a statically typed, free-form, multi-paradigm, compiled, general-purpose programming language. It is regarded as an intermediate-level language, as it comprises a combination of both high-level and low-level language features. It was developed by Bjarne Stroustrup starting in 1979 at Bell...
libraries still have the
assert.hAssert.hassert.h is a header file in the standard library of the C programming language that defines the C preprocessor macro assert. The macro implements an assertion, which can be used to verify assumptions made by the program and print a diagnostic message if this assumption is false...
available.The danger of assertions is that they may cause side effects either by changing memory data or by changing thread timing. Assertions should be implemented carefully so they cause no side effects on program code.
Assertion constructs in a language allow for easy test-driven development
Test-driven development
Test-driven development is a software development process that relies on the repetition of a very short development cycle: first the developer writes a failing automated test case that defines a desired improvement or new function, then produces code to pass that test and finally refactors the new...
(TDD) without the use of a third-party library.
Assertions during the development cycle
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 traceStack trace
A stack trace is a report of the active stack frames at a certain point in time during the execution of a program.It is commonly used during interactive and post-mortem debugging...
, or even the full program state if the environment supports core dump
Core dump
In computing, a core dump consists of the recorded state of the working memory of a computer program at a specific time, generally when the program has terminated abnormally...
s or if the program is running in a debugger
Debugger
A debugger or debugging tool is a computer program that is used to test and debug other programs . The code to be examined might alternatively be running on an instruction set simulator , a technique that allows great power in its ability to halt when specific conditions are encountered but which...
), the programmer can usually fix the problem. Thus assertions provide a very powerful tool in debugging.
Static assertions
Assertions that are checked at compile time are called static assertions. They should always be well-commented.Static assertions are particularly useful in compile time template metaprogramming
Template metaprogramming
Template metaprogramming is a metaprogramming technique in which templates are used by a compiler to generate temporary source code, which is merged by the compiler with the rest of the source code and then compiled. The output of these templates include compile-time constants, data structures, and...
, but can also be used in low-level languages in C by introducing illegal code if (and only if) the assertion fails. For example, in C a static assertion can be implemented like this:
If the
(BOOLEAN CONDITION)
part evaluates to false then the above code will not compile because the compiler will not allow two case labels with the same constant. The boolean expression must be a compile-time constant value, for example (sizeof(int)4)
would be a valid expression in that context. This construct does not work at file scope (i.e. not inside a function), and so it must be wrapped inside a function.Another popular way of implementing assertions in C is:
If the
(BOOLEAN CONDITION)
part evaluates to false then the above code will not compile because arrays may not have a negative length. If in fact the compiler allows a negative length then the initialization byte (the '!'
part) should cause even such over-lenient compilers to complain. The boolean expression must be a compile-time constant value, for example (sizeof(int)4)
would be a valid expression in that context.Both of these methods require a method of constructing unique names. Modern compilers support a __COUNTER__ preprocessor define that facilitates the construction of unique names, by returning monotonically increasing numbers for each compilation unit.
Disabling assertions
Most languages allow assertions to be enabled or disabled globally, and sometimes independently. Assertions are often enabled during development and disabled during final testing and on release to the customer. Not checking assertions avoids the cost of evaluating the assertions while, assuming the assertions are free of side effects, still producing the same result under normal conditions. Under abnormal conditions, disabling assertion checking can mean that a program that would have aborted will continue to run. This is sometimes preferable.Some languages, including C/C++, completely remove assertions at compile time using the preprocessor
Preprocessor
In computer science, a preprocessor is a program that processes its input data to produce output that is used as input to another program. The output is said to be a preprocessed form of the input data, which is often used by some subsequent programs like compilers...
. Java requires an option to be passed to the run-time engine in order to enable assertions. Absent the option, assertions are bypassed, but they always remain in the code unless optimised away by a JIT compiler at run-time or excluded by an if(false) condition at compile time, thus they need not have a run-time space or time cost in Java either.
Programmers can always build checks into their code that are always active by bypassing or manipulating the language's normal assertion-checking mechanisms.
Comparison with error handling
It is worth distinguishing assertions from routine error-handling. Assertions should be used to document logically impossible situations and discover programming errors — 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 unwise: assertions do not allow for recovery from errors; an assertion failure will normally 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:
Here, the programmer is aware that
mallocMallocC dynamic memory allocation refers to performing dynamic memory allocation in the C via a group of functions in the C standard library, namely malloc, realloc, calloc and free....
will return a NULL
pointer if memory is not allocated. This is possible: the operating system does not guarantee that every call to malloc
will succeed. If an out of memory error occurs the program will immediately abort. Without the assertion, the program would continue running until ptr was dereferenced, and possibly longer, depending on the specific hardware being used. So long as assertions are not disabled, an immediate exit is assured. But if a graceful failure is desired, the program has to handle the failure. For example, a server may have multiple clients, or may hold resources that will not be released cleanly, or it may have uncommitted changes to write to a datastore. In such cases it is better to fail a single transaction than to abort abruptly.See also
- Assertion definition languageAssertion definition languageThe Assertion Definition Language is a specification language providing a formal grammar to specify behaviour and interfaces for computer software. ADL uses function pre- and post-conditions to specify interfaces, and is designed to provide an intermediary between informal English language...
- Design by contractDesign by contractDesign by contract , also known as programming by contract and design-by-contract programming, is an approach to designing computer software...
- Exception handlingException handlingException handling is a programming language construct or computer hardware mechanism designed to handle the occurrence of exceptions, special conditions that change the normal flow of program execution....
- Hoare logicHoare logicHoare logic is a formal system with a set of logical rules for reasoning rigorously about the correctness of computer programs. It was proposed in 1969 by the British computer scientist and logician C. A. R. Hoare, and subsequently refined by Hoare and other researchers...
- Static code analysisStatic code analysisStatic program analysis is the analysis of computer software that is performed without actually executing programs built from that software In most cases the analysis is performed on some version of the source code and in the other cases some form of the object code...
- Java Modeling LanguageJava Modeling LanguageThe Java Modeling Language is a specification language for Java programs, using Hoare style pre- and postconditions and invariants, that follows the design by contract paradigm...
External links
- The benefits of programming with assertions by Philip Guo (Stanford University), 2008.
- Java: