In
computer programming
Computer programming is the process of performing a particular computation (or more generally, accomplishing a specific computing result), usually by designing and building an executable computer program. Programming involves tasks such as anal ...
, specifically when using the
imperative programming
In computer science, imperative programming is a programming paradigm of software that uses statements that change a program's state. In much the same way that the imperative mood in natural languages expresses commands, an imperative program ...
paradigm, an assertion is a
predicate
Predicate or predication may refer to:
* Predicate (grammar), in linguistics
* Predication (philosophy)
* several closely related uses in mathematics and formal logic:
**Predicate (mathematical logic)
**Propositional function
**Finitary relation, o ...
(a
Boolean-valued function
A Boolean-valued function (sometimes called a predicate or a proposition) is a function of the type f : X → B, where X is an arbitrary set and where B is a Boolean domain, i.e. a generic two-element set, (for example B = ), whose elements are i ...
over the
state space
A state space is the set of all possible configurations of a system. It is a useful abstraction for reasoning about the behavior of a given system and is widely used in the fields of artificial intelligence and game theory.
For instance, the to ...
, usually expressed as a
logical proposition
In logic and linguistics, a proposition is the meaning of a declarative sentence. In philosophy, " meaning" is understood to be a non-linguistic entity which is shared by all sentences with the same meaning. Equivalently, a proposition is the no ...
using the
variables of a program) connected to a point in the program, that always should evaluate to true at that point in code execution. Assertions can help a programmer read the code, help a
compiler
In computing, a compiler is a computer program that translates computer code written in one programming language (the ''source'' language) into another language (the ''target'' language). The name "compiler" is primarily used for programs tha ...
compile it, or help the program detect its own defects.
For the latter, some programs check assertions by actually evaluating the predicate as they run. Then, if it is not in fact true – an assertion failure – the program considers itself to be broken and typically deliberately
crashes or throws an assertion failure
exception.
Details
The following code contains two assertions,
x > 0
and
x > 1
, and they are indeed true at the indicated points during execution:
x = 1;
assert x > 0;
x++;
assert x > 1;
Programmers can use assertions to help specify programs and to reason about program correctness. For example, a
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.
If a precondition is violated, the effect of the s ...
—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 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 wit ...
—placed at the end—describes the expected state at the end of execution. For example:
x > 0 x > 1
.
The example above uses the notation for including assertions used by
C. A. R. Hoare
Sir Charles Antony Richard Hoare (Tony Hoare or C. A. R. Hoare) (born 11 January 1934) is a British computer scientist who has made foundational contributions to programming languages, algorithms, operating systems, formal verification, and c ...
in his 1969 article. 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:
x = 5;
x = x + 1;
//
The braces included in the comment help distinguish this use of a comment from other uses.
Libraries
A library is a collection of Document, materials, books or media that are accessible for use and not just for display purposes. A library provides physical (hard copies) or electronic media, digital access (soft copies) materials, and may be a ...
may provide assertion features as well. For example, in C using
glibc
The GNU C Library, commonly known as glibc, is the GNU Project's implementation of the C standard library. Despite its name, it now also directly supports C++ (and, indirectly, other programming languages). It was started in the 1980s ...
with C99 support:
#include
int f(void)
Several modern programming languages include checked assertions –
statements
Statement or statements may refer to: Common uses
*Statement (computer science), the smallest standalone element of an imperative programming language
*Statement (logic), declarative sentence that is either true or false
*Statement, a declarative ...
that are checked at
runtime or sometimes statically. If an assertion evaluates to false at runtime, 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
Eiffel, assertions form part of the design process; other languages, such as
C and
Java
Java (; id, Jawa, ; jv, ꦗꦮ; su, ) is one of the Greater Sunda Islands in Indonesia. It is bordered by the Indian Ocean to the south and the Java Sea to the north. With a population of 151.6 million people, Java is the world's mo ...
, use them 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
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.
If a precondition is violated, the effect of the s ...
s), and the state the code expects to result in when it is finished running (
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 wit ...
s); they can also specify
invariants of a
class
Class or The Class may refer to:
Common uses not otherwise categorized
* Class (biology), a taxonomic rank
* Class (knowledge representation), a collection of individuals or objects
* Class (philosophy), an analytical concept used differently ...
.
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
comments 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.
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
Java
Java (; id, Jawa, ; jv, ꦗꦮ; su, ) is one of the Greater Sunda Islands in Indonesia. It is bordered by the Indian Ocean to the south and the Java Sea to the north. With a population of 151.6 million people, Java is the world's mo ...
code:
int total = countNumberOfUsers();
if (total % 2 0) else
In
Java
Java (; id, Jawa, ; jv, ꦗꦮ; su, ) is one of the Greater Sunda Islands in Indonesia. It is bordered by the Indian Ocean to the south and the Java Sea to the north. With a population of 151.6 million people, Java is the world's mo ...
,
%
is the ''
remainder
In mathematics, the remainder is the amount "left over" after performing some computation. In arithmetic, the remainder is the integer "left over" after dividing one integer by another to produce an integer quotient ( integer division). In algeb ...
'' operator (''
modulo
In computing, the modulo operation returns the remainder or signed remainder of a division, after one number is divided by another (called the '' modulus'' of the operation).
Given two positive numbers and , modulo (often abbreviated as ) is ...
''), and in Java, if its first operand is negative, the result can also be negative (unlike the modulo used in mathematics). 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 often obscure 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
C,
C++
C++ (pronounced "C plus plus") is a high-level general-purpose programming language created by Danish computer scientist Bjarne Stroustrup as an extension of the C programming language, or "C with Classes". The language has expanded significan ...
, and
Java
Java (; id, Jawa, ; jv, ꦗꦮ; su, ) is one of the Greater Sunda Islands in Indonesia. It is bordered by the Indian Ocean to the south and the Java Sea to the north. With a population of 151.6 million people, Java is the world's mo ...
. 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
D such an assertion is added automatically when a
switch
statement doesn't contain a
default
clause.
In
Java
Java (; id, Jawa, ; jv, ꦗꦮ; su, ) is one of the Greater Sunda Islands in Indonesia. It is bordered by the Indian Ocean to the south and the Java Sea to the north. With a population of 151.6 million people, Java is the world's mo ...
, 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
C, they are added on by the standard header
assert.h
defining
assert (''assertion'')
as a macro that signals an error in the case of failure, usually terminating the program. In
C++
C++ (pronounced "C plus plus") is a high-level general-purpose programming language created by Danish computer scientist Bjarne Stroustrup as an extension of the C programming language, or "C with Classes". The language has expanded significan ...
, both
assert.h
and
cassert
headers provide the
assert
macro.
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 (TDD) is a software development process relying on software requirements being converted to test cases before software is fully developed, and tracking all software development by repeatedly testing the software against al ...
(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 trace
In computing, a stack trace (also called stack backtrace or stack traceback) is a report of the active stack frames at a certain point in time during the execution of a program. When a program is run, memory is often dynamically allocated in two ...
, or even the full program state if the environment supports
core dump
In computing, a core dump, memory dump, crash dump, storage dump, system dump, or ABEND dump consists of the recorded state of the working memory of a computer program at a specific time, generally when the program has crashed or otherwise termina ...
s or if the program is running in a
debugger
A debugger or debugging tool is a computer program used to test and debug other programs (the "target" program). The main use of a debugger is to run the target program under controlled conditions that permit the programmer to track its executi ...
), the programmer can usually fix the problem. Thus assertions provide a very powerful tool in debugging.
Assertions in production environment
When a program is deployed to
production, assertions are typically turned off, to avoid any overhead or side effects they may have. In some cases assertions are completely absent from deployed code, such as in C/C++ assertions via macros. In other cases, such as Java, assertions are present in the deployed code, and can be turned on in the field for debugging.
Assertions may also be used to promise the compiler that a given edge condition is not actually reachable, thereby permitting certain
optimizations that would not otherwise be possible. In this case, disabling the assertions could actually reduce performance.
Static assertions
Assertions that are checked at compile time are called static assertions.
Static assertions are particularly useful in compile time
template metaprogramming
Template metaprogramming (TMP) 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 t ...
, but can also be used in low-level languages like C by introducing illegal code if (and only if) the assertion fails.
C11 C11, C.XI, C-11 or C.11 may refer to:
Transport
* C-11 Fleetster, a 1920s American light transport aircraft for use of the United States Assistant Secretary of War
* Fokker C.XI, a 1935 Dutch reconnaissance seaplane
* LET C-11, a license-build var ...
and
C++11 C11, C.XI, C-11 or C.11 may refer to:
Transport
* C-11 Fleetster, a 1920s American light transport aircraft for use of the United States Assistant Secretary of War
* Fokker C.XI, a 1935 Dutch reconnaissance seaplane
* LET C-11, a license-build ...
support static assertions directly through
static_assert
. In earlier C versions, a static assertion can be implemented, for example, like this:
#define SASSERT(pred) switch(0)
SASSERT( BOOLEAN CONDITION );
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
sizeof is a unary operator in the programming languages C and C++. It generates the storage size of an expression or a data type, measured in the number of ''char''-sized units. Consequently, the construct ''sizeof (char)'' is guaranteed to be ' ...
(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:
static char const static_assertion (BOOLEAN CONDITION)
? 1 : -1
= ;
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.
D provides static assertions through the use of
static assert
.
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
In medicine, a side effect is an effect, whether therapeutic or adverse, that is secondary to the one intended; although the term is predominantly employed to describe adverse effects, it can also apply to beneficial, but unintended, consequenc ...
) 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 and
C++
C++ (pronounced "C plus plus") is a high-level general-purpose programming language created by Danish computer scientist Bjarne Stroustrup as an extension of the C programming language, or "C with Classes". The language has expanded significan ...
, can completely remove assertions at compile time using the
preprocessor
In computer science, a preprocessor (or precompiler) is a program that processes its input data to produce output that is used as input in another program. The output is said to be a preprocessed form of the input data, which is often used by so ...
.
Similarly, launching the
Python interpreter with "-O" (for "optimize") as an argument will cause the Python code generator to not emit any bytecode for asserts.
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 at compile time via the programmer manually placing each assertion behind an
if (false)
clause.
Programmers can build checks into their code that are always active by bypassing or manipulating the language's normal assertion-checking mechanisms.
Comparison with error handling
Assertions are distinct from routine
error-handling. Assertions document logically impossible situations and discover programming errors: if the impossible occurs, then something fundamental is clearly wrong with the program. 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; and assertions are often disabled in production code. 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);
// use ptr
...
Here, the programmer is aware that
malloc
C dynamic memory allocation refers to performing manual memory management for dynamic memory allocation in the C programming language via a group of functions in the C standard library, namely , , , and .
The C++ programming language includes t ...
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.
Another error is to rely on side effects of expressions used as arguments of an assertion. One should always keep in mind that assertions might not be executed at all, since their sole purpose is to verify that a condition which should always be true does in fact hold true. Consequently, if the program is considered to be error-free and released, assertions may be disabled and will no longer be evaluated.
Consider another version of the previous example:
int *ptr;
// Statement below fails if malloc() returns NULL,
// but is not executed at all when compiling with -NDEBUG!
assert(ptr = malloc(sizeof(int) * 10));
// use ptr: ptr isn't initialised when compiling with -NDEBUG!
...
This might look like a smart way to assign the return value of
malloc
to
ptr
and check if it is
NULL
in one step, but the
malloc
call and the assignment to
ptr
is a side effect of evaluating the expression that forms the
assert
condition. When the
NDEBUG
parameter is passed to the compiler, as when the program is considered to be error-free and released, the
assert()
statement is removed, so
malloc()
isn't called, rendering
ptr
uninitialised. This could potentially result in a
segmentation fault
In computing, a segmentation fault (often shortened to segfault) or access violation is a fault, or failure condition, raised by hardware with memory protection, notifying an operating system (OS) the software has attempted to access a restrict ...
or similar
null pointer
In computing, a null pointer or null reference is a value saved for indicating that the pointer or reference does not refer to a valid object. Programs routinely use null pointers to represent conditions such as the end of a list of unknown leng ...
error much further down the line in program execution, causing bugs that may be
sporadic and/or difficult to track down. Programmers sometimes use a similar VERIFY(X) define to alleviate this problem.
Modern compilers may issue a warning when encountering the above code.
History
In 1947 reports by
von Neumann Von Neumann may refer to:
* John von Neumann (1903–1957), a Hungarian American mathematician
* Von Neumann family
* Von Neumann (surname), a German surname
* Von Neumann (crater), a lunar impact crater
See also
* Von Neumann algebra
* Von Ne ...
and
Goldstine on their design for the
IAS machine
The IAS machine was the first electronic computer built at the Institute for Advanced Study (IAS) in Princeton, New Jersey. It is sometimes called the von Neumann machine, since the paper describing its design was edited by John von Neumann, a ...
, they described algorithms using an early version of
flow charts
A flowchart is a type of diagram that represents a workflow or process. A flowchart can also be defined as a diagrammatic representation of an algorithm, a step-by-step approach to solving a task.
The flowchart shows the steps as boxes of v ...
, in which they included assertions: "It may be true, that whenever C actually reaches a certain point in the flow diagram, one or more bound variables will necessarily possess certain specified values, or possess certain properties, or satisfy certain properties with each other. Furthermore, we may, at such a point, indicate the validity of these limitations. For this reason we will denote each area in which the validity of such limitations is being asserted, by a special box, which we call an assertion box."
The assertional method for proving correctness of programs was advocated by
Alan Turing
Alan Mathison Turing (; 23 June 1912 – 7 June 1954) was an English mathematician, computer scientist, logician, cryptanalyst, philosopher, and theoretical biologist. Turing was highly influential in the development of theoretical ...
. In a talk "Checking a Large Routine" at Cambridge, June 24, 1949 Turing suggested: "How can one check a large routine in the sense of making sure that it's right? In order that the man who checks may not have too difficult a task, the programmer should make a number of definite ''assertions'' which can be checked individually, and from which the correctness of the whole program easily follows".
[Alan Turing]
Checking a Large Routine
1949; quoted in C. A. R. Hoare, "The Emperor's Old Clothes", 1980 Turing Award lecture.
See also
*
Assertion definition language
The Assertion Definition Language (ADL) is a specification language providing a formal grammar to specify behaviour and interfaces for computer software. ADL uses function pre- and postconditions to specify interfaces and is designed to provide an ...
*
Design by contract
*
Exception handling
In computing and computer programming, exception handling is the process of responding to the occurrence of ''exceptions'' – anomalous or exceptional conditions requiring special processing – during the execution of a program. In general, an ...
*
Hoare logic
Hoare logic (also known as Floyd–Hoare logic or Hoare rules) 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 l ...
*
Static code analysis
In computer science, static program analysis (or static analysis) is the analysis of computer programs performed without executing them, in contrast with dynamic program analysis, which is performed on programs during their execution.
The term ...
*
Java Modeling Language
*
Invariant (computer science)
In mathematics, an invariant is a property of a mathematical object (or a class of mathematical objects) which remains unchanged after operations or transformations of a certain type are applied to the objects. The particular class of objects ...
References
{{reflist
External links
*
A historical perspective on runtime assertion checking in software development' by Lori A. Clarke, David S. Rosenblum in: ACM SIGSOFT Software Engineering Notes 31(3):25-37, 2006
*
Assertions: a personal perspective' by C.A.R. Hoare in: IEEE Annals of the History of Computing, Volume: 25, Issue: 2 (2003), Page(s): 14 - 25
*
My Compiler Does Not Understand Me' by Poul-Henning Kamp in: ACM Queue 10(5), May 2012
*
Use of Assertions' by John Regehr
Formal methods
Logic in computer science
Conditional constructs
Debugging