mirror of
https://github.com/boostorg/contract.git
synced 2026-02-26 16:42:19 +00:00
65 lines
4.1 KiB
Plaintext
65 lines
4.1 KiB
Plaintext
|
|
[/ Copyright (C) 2008-2016 Lorenzo Caminiti]
|
|
[/ Distributed under the Boost Software License, Version 1.0 (see accompanying]
|
|
[/ file LICENSE_1_0.txt or a copy at http://www.boost.org/LICENSE_1_0.txt).]
|
|
[/ See: http://www.boost.org/doc/libs/release/libs/contract/doc/html/index.html]
|
|
|
|
[section Introduction]
|
|
|
|
Contract Programming allows to specify preconditions, postconditions, and class invariants that are automatically checked when functions are executed at run-time.
|
|
These conditions assert program specifications within the source code itself allowing to find bugs more quickly during testing, making the code self-documenting, and increasing overall software quality.
|
|
|
|
The following example shows how to use this library to program contracts for a member function similar to `std::vector::push_back` (the somewhat arbitrary `pushable` base class is introduced here just to illustrate subcontracting, see [@../../example/features/introduction.cpp =introduction.cpp=]):
|
|
[footnote
|
|
For simplicity, the full contracts of the `vector` class are not programmed here (see the __Examples__ section for a much more comprehensive version of `vector`'s contracts).
|
|
]
|
|
|
|
[import ../example/features/introduction.cpp]
|
|
[introduction]
|
|
|
|
This library executes the following steps when the `vector::push_back` function above is called at run-time (see __Contract_Programming_Overview__):
|
|
|
|
* First, the class invariants and the function preconditions are checked.
|
|
* Then, the function body following the contract declaration is executed.
|
|
* Last, the class invariants and the function postconditions are checked.
|
|
* When subcontracting (like in the example above), this library will automatically check derived and base preconditions in __OR__, derived and base postconditions in __AND__, derived and base class invariants in __AND__.
|
|
|
|
For example, if there is a bug in the function caller for which `push_back` is called when `size` is equal to `max_size` then the execution of the program will terminate with an error message similar to the following (so it will be evident that the bug is in the caller):
|
|
|
|
[pre
|
|
precondition assertion "size() < max_size()" failed: file "introduction.cpp", line 35
|
|
]
|
|
|
|
Instead, if there is a bug in the `push_back` implementation for which `size` is not increased by `1` after `value` is added to `vector` by the function body then the execution will terminate with an error message similar to the following (so it will be evident that the bug is in the `push_back` body):
|
|
|
|
[pre
|
|
postcondition assertion "size() == *old_size + 1" failed: file "introduction.cpp", line 38
|
|
]
|
|
|
|
Similarly, if there is a bug in the `push_back` implementation for which `size` is not kept greater or equal than `capacity` then the execution will terminate with an error message similar to the following:
|
|
|
|
[pre
|
|
exit invariant assertion "size() <= capacity()" failed: file "introduction.cpp", line 25
|
|
]
|
|
|
|
Finally, if the class invariant check failed on entering the `push_back` function call, before executing the `push_back` implementation, then the execution will terminate with an error message similar to the following:
|
|
|
|
[pre
|
|
entry invariant assertion "size() <= capacity()" failed: file "introduction.cpp", line 25
|
|
]
|
|
|
|
By default, when an assertion fails this library prints an error message to the standard error `std::cerr` and terminates the program calling `std::terminate` (this behaviour can be customized to take any user-defined action including throwing exceptions, see the __Throw_on_Failure__ section).
|
|
Note that the error message printed by this library contains information to easily and uniquely identify the point in the program at which the assertion failed.
|
|
[footnote
|
|
*Rationale:*
|
|
The assertion failure messages generated by this library follows a format similar to the messages printed by Clang when the C-style `assert` macro fails.
|
|
]
|
|
|
|
[note
|
|
C++11 lambda functions are necessary to use this library without having to manually program a significant amount of boiler-plate code (but see the __No_Lambda_Functions__ section).
|
|
All other C++11 features (like `auto` declarations) are not really necessary even if they are sometimes used in this documentation for convenience.
|
|
]
|
|
|
|
[endsect]
|
|
|