<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>

<meta http-equiv="Content-Type" content="text/html;charset=US-ASCII">

<style type="text/css">
body { color: #000000; background-color: #FFFFFF; }
del { text-decoration: line-through; color: #8B0040; }
ins { text-decoration: underline; color: #005100; }
p.example { margin: 2em; }
pre.example { margin: 2em; }
div.example { margin: 2em; }
code.extract { background-color: #F5F6A2; }
pre.extract { margin: 2em; background-color: #F5F6A2;
  border: 1px solid #E1E28E; }
p.function { }
p.attribute { text-indent: 3em; }
blockquote.std { color: #000000; background-color: #F1F1F1;
  border: 1px solid #D1D1D1; padding: 0.5em; }
blockquote.stddel { text-decoration: line-through; color: #000000;
  background-color: #FFEBFF; border: 1px solid #ECD7EC; padding: 0.5em; }
blockquote.stdins { text-decoration: underline; color: #000000;
  background-color: #C8FFC8; border: 1px solid #B3EBB3; padding: 0.5em; }
table { border: 1px solid black; border-spacing: 0px;
  border-collapse: collapse; margin-left: auto; margin-right: auto; }
th { text-align: left; vertical-align: top; padding: 0.2em;
  border: 1px solid black; }
td { text-align: left; vertical-align: top; padding: 0.2em;
  border: 1px solid black;
}
</style>


<title>The Use and Implementation of Contracts</title>
</head>
<body>
<h1>The Use and Implementation of Contracts</h1>

<p>
ISO/IEC JTC1 SC22 WG21 EWG P0147R0 - 2015-11-08
</p>

<p>
Lawrence Crowl, Lawrence@Crowl.org
</p>

<p>
<a href="#Introduction">Introduction</a><br>
<a href="#Writing">Writing Contracts</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Arguments">Preconditions on Arguments</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Return">Postconditions on Return Values</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Chaining">Chaining Conditions</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Inverse">Postconditions as Inverse Functions</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Completeness">Completeness via Code</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#WideNarrow">Wide versus Narrow Contracts</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Broken">Broken Contracts</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Identity">Conditions on Object Identity</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#State">Conditions on Object State</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Invariants">Invariants</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Exceptions">Contracts and Exceptions</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Inheritance">Inheritance</a><br>
<a href="#Expectations">Writing Expectations</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Branches">Optimizing Branches</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Algorithms">Selecting Algorithms</a><br>
<a href="#Managing">Managing Contracts</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Compiling">Compiling Contracts</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Characterizing">Characterizing Contracts</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Adopting">Adopting Contracts</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Testing">Testing Contracts</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#Handlers">Managing Handlers</a><br>
<a href="#Implementing">Implementing Contracts</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#DynamicEval">Dynamic Evaluation</a><br>
&nbsp;&nbsp;&nbsp;&nbsp;<a href="#StaticEval">Static Evaluation</a><br>
<a href="#References">References</a><br>
<a href="#Bibliography">Bibliography</a><br>
</p>


<h2><a name="Introduction">Introduction</a></h2>

<p>
Contracts are the preconditions, invariants and postconditions
that define the behavior of a software abstraction.
The common practice is that these contracts appear in vague documentation,
if at all.
The standard library uses a much more formal documentation to define behavior.
That documentation is critical to interoperable software.
However, that documentation is in prose, not code.
</p>

<p>
Moving contracts from prose to code has several benefits.
</p>

<blockquote>
<dl>

<dt>Contracts in code enables automatic checking of correctness.</dt>
<dd>
<p>
The checking can occur at run time via inserted check code.
It can also occur at compile time via static analysis.
The simple case for static analysis is determining
that a constant value does not satisfy a condition.
A more involved static analysis could extend to finding
that the postcondition that produced a value
is weaker than the precondition that uses the value.
</p>
</dd>

<dt>Contracts in code enables more optimization of programs.</dt>
<dd>
<p>
A contract constrains the behavior of a function,
and compilers exploit constraints.
As examples, a precondition that states a parameter is not null
can enable the compiler to remove checks for null pointers.
Similarly, an invariant that a loop bound is 0 mod 4
enables the compiler to avoid emitting tail code
when unrolling loops.
</p>
</dd>

<dt>Contracts in code encourages better contracts.</dt>
<dd>
<p>
Specifications generally become less ambiguous and more complete
as they become more formal.
Furthermore,
programmers tend to question the correctness and completeness of code
much more than they do of prose.
Taken together,
these points mean that contracts in code
will lead to fewer misunderstandings and defects,
particularly for programmers new to the code.
</p>
</dd>

</dl>
</blockquote>

<p>
While we could realize many of these benefits for the standard library
by baking knowledge of the library into the compiler,
the approach would provide no value to other libraries.
We need a general solution.
</p>

<p>
This paper does not propose a specific solution.
It does use a syntax somewhat close to that proposed in 
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1962.html">N1962
Proposal to add Contract Programming to C++</a>.
For specific proposals and other discussion,
see the <a href="#Bibliography">Bibliography</a> below.
</p>

<p>
Instead, this paper
explores the writing of contracts with some examples,
explores the practical issues in managing of contract compilation,
and outlines an implementation that addresses those issues.
In the process,
some constraints arise on the semantics of any specific contract proposal.
</p>


<h2><a name="Writing">Writing Contracts</a></h2>

<p>
All contracts start life as a vague goal,
which is then refined to a usable contract.
Writing a refined contract can be hard,
whether or not the contract is in prose or in code.
In this section,
we show through a sequence of examples
how that refinement may happen.
In the process,
we identify constraints on a contract mechanism.
The working assumption in this section
is that the goal is a complete contract in code.
Where completeness in code is not possible or desirable,
the coded parts of the contract remain valuable.
</p>


<h3><a name="Arguments">Preconditions on Arguments</a></h3>

<p>
Preconditions generally describe the domain of the computation.
The (real-valued) square root function has a well-known domain.
</p>
<pre class="example">
<code>double sqrt(double input)
  precondition { input &gt;= 0.0; };</code>
</pre>

<p>
However, IEEE floating-point <a href="#IEEE">[IEEE]</a> numbers
are not real numbers.
Any contract on a IEEE floating-point numbers
must take into account the 'extra' values.
Among them are negative zero, infinity and not-a-number (NaN).
</p>
<pre class="example">
<code>double sqrt(double input)
  precondition { ! isSignMinus(input); input &lt; +Infinity; };</code>
</pre>

<p>
The <a href="#IEEE">[IEEE]</a> operation <code>isSignMinus</code>
tests the sign bit,
enabling one to distinguish between positive zero and negative zero.
So, the first condition excludes all negative values.
The second condition excludes positive infinity.
It also excludes NaNs
because NaNs are never less than any other value.
</p>

<p>
In any event,
<strong>preconditions must identify the subset of possible input values
that constitutes the domain of the function</strong>.
</p>


<h3><a name="Return">Postconditions on Return Values</a></h3>

<p>
Postconditions define the return value of a function
given that the preconditions have been met.
</p>
<pre class="example">
<code>vector&lt;int&gt; sort(vector&lt;int&gt; arg)
  postcondition { is_sorted(result); };</code>
</pre>

<p>
While necessary, the above postcondition is not sufficient.
It must also say that the output is a permutation of the input.
</p>
<pre class="example">
<code>vector&lt;int&gt; sort(vector&lt;int&gt; arg)
  postcondition { is_sorted(result); is_permutation(arg, result); };</code>
</pre>

<p>
So,
<strong>postconditions must describe the relationship
of the result to the values in the domain of the input</strong>.
</p>


<h3><a name="Chaining">Chaining Conditions</a></h3>

<p>
In general, we satisfy the preconditions of one function
with the postconditions of earlier function.
Indeed, such chaining is unavoidable
if we consider primitive operations as functions with contracts.
</p>

<p>
In the example above,
the <code>is_sorted</code> condition
would <em>a priori</em> satisfy an <code>is_sorted</code> precondition
that <code>is_permutation</code> might have on its second argument.
</p>

<p>
The chaining of postconditions to preconditions implies that
both are inherently part of the interface to a function.
So, <strong>preconditions and postconditions
should be visible as part of the function header</strong>.
</p>


<h3><a name="Inverse">Postconditions as Inverse Functions</a></h3>

<p>
The obvious postcondition for <code>sqrt</code>,
and the one that prose documentation would typically state,
does not work.
<pre class="example">
<code>double sqrt(double input)
  precondition { ! isSignMinus(input); input &lt; +Infinity; };
  postcondition { result == sqrt(input); };</code>
</pre>

<p>
The problem is that <code>sqrt</code> is using itself to define itself.
Instead, <strong>postconditions should often be specified
in terms of the inverse function</strong>.
</p>
<pre class="example">
<code>double sqrt(double input)
  precondition { ! isSignMinus(input); input &lt; +Infinity; };
  postcondition { result &gt;= 0.0; result*result == input; };</code>
</pre>


<h3><a name="Completeness">Completeness via Code</a></h3>

<p>
Unfortunately, the above <code>sqrt</code> specification
ignores the rounding inevitable with a discrete representation of real numbers.
This lack of completeness arises because
<strong>programmers are less likely to notice
incompleteness in prose specifications</strong>.
For completeness,
the <code>sqrt</code> specification needs to define
how close the result must to the true square root.
One approach is the following.
</p>
<pre class="example">
<code>double sqrt(double input)
  precondition { ! isSignMinus(input); input &lt; +Infinity; };
  postcondition { result &gt;= 0.0;
                  abs(result*result-input) &lt; input*1e-16; };</code>
</pre>

<p>
This specification is weaker than typical guarantees,
which require "as close as is representable".
For that, we introduce a helper function
to determine if the result is close enough.
Central to this determination
is the use of <a href="#IEEE">[IEEE]</a> operations
<code>nextUp</code> and <code>nextDown</code>
which provide access to the closest representable number.
In essence, we define the result
to be within the range implied by the closest computations.
(One can, of course, generalize the 'close enough' function
to accept an arbitrary function.
Such a function would be useful
in the specification of a variety of contracts.)
</p>
<pre class="example">
<code>bool sqrt_close_enough(double input, double result) {
  if ( input &lt; result * result )
    return result * max(nextDown(result), 0.0) &lt;= input;
  else if (result * result &lt; input )
    return input &lt;= result * nextUp(result);
  else
    return result * result == input;
}</code>
</pre>

<p>
Now we can provide a more complete contract.
</p>
<pre class="example">
<code>double sqrt(double input)
  precondition { ! isSignMinus(input); input &lt; +Infinity; };
  postcondition { result &gt;= 0.0;
                  sqrt_close_enough(input, result); };</code>
</pre>

<p>
<strong>The use of helper functions
is an important tool in the specification of contracts.</strong>
Among other things,
they provide the compiler with a handle
to match preconditions with postconditions.
</p>

<p>
Given user-control of rounding modes, more specification is needed.
At this point, one is tempted to say "too much work"!
However, failing to do such work when writing the specification
simply defers the work to support calls.
</p>


<h3><a name="WideNarrow">Wide versus Narrow Contracts</a></h3>

<p>
The contract for <code>sqrt</code> presented above
is <em>not</em> what <a href="#IEEE">[IEEE]</a> requires.
The IEEE contract has no preconditions.
Instead, it specifies the behavior for all possible input.
In the terminology of John Lakos,
the IEEE <code>sqrt</code> has a wide contract.
</p>

<p>
In effect,
the nominal preconditions have been moved to the postcondition
as exceptional values.
</p>
<pre class="example">
<code>double sqrt(double input)
  postcondition {
    if ( isNaN(input) || input &lt; 0.0 ) isNaN(result);
    else if ( input == 0.0 && isSignMinus(input) )
           result == 0.0 && isSignMinus(result);
    else if ( input == +Infinity ) result == +Infinity;
    else sqrt_close_enough(input, result); };</code>
</pre>

<p>
This approach 
follows the common practice of not failing on any possible input.
The approach is a consequence of
having of no contract mechanism in the language
and of
a desire of programmers not to have 'their' function fail.
Unfortunately, the approach usually does not eliminate the failure,
it simply defers it to later in the execution,
where the root cause is harder to discern.
So usually,
<strong>the precondition should restrict the domain to
the region where the function can provide a service</strong>.
<p>

<p>
Given the above discussion,
should we conclude that <a href="#IEEE">[IEEE]</a> is wrong?
No, we should not.
First, an intermediate computation with bad data
may not affect the final result.
The design chosen enables irrelevant bad computation to disappear.
Second, floating-point computation is performance-sensitive.
An ability to stop a computation given a broken precondition
would likely reduce the performance of hardware and hence applications.
Given those observations,
the designers felt that the better approach
would be for programmers to check a computation's result for validity
and redo a failing computation with another algorithm.
</p>

<p>
Floating-point computation is not the only scenario
in which preconditions may be inappropriate.
In particular,
<strong>preconditions on data arriving from input are fragile</strong>.
The problem is that the data may be produced
in an environment that is ignorant of the conditions on that data.
The better approach is to explicitly test for inappropriate data
and report the problem to the user.
</p>

<p>
Given that wide contracts need no preconditions,
we can conclude that
<strong>the purpose of preconditions is to define narrow contracts</strong>.
Furthermore, a very narrow contract will throw no exceptions,
and hence <strong>contracts enable noexcept functions</strong>.
</p>


<h3><a name="Broken">Broken Contracts</a></h3>

<p>
An important question to consider is the semantics of a broken contract.
The goal of a contract mechanism is to enable programmers to develop
programs that are correct and hence do not need checking for correctness.
When checking is not enabled,
a broken contract can lead to memory corruption and more.
</p>

<p>
When checking is enabled,
what happens when a broken contract is detected?
We must to something,
and that something is defined by a handler.
That handler is generally not defined by the programmer
that writes a contract.
Indeed, the contract programmer usually has no idea what a handler may do.
</p>

<p>
A consequence of the above discussion is that
<strong>a postcondition should <em>not</em> make any assertions about results
when preconditions are false</strong>.
Doing so would imply that
preconditions are weaker in practice than in definition.
</p>

<p>
As a consequence,
the unofficial contracts study group has a working definition
something along the lines of
"the program has undefined behavior on exit from a broken contract".
This statement is true even if the contract is not evaluated.
</p>

<p>
There is a critical distinction to be made here between
the standard not defining behavior
and the compiler not defining behavior.
Compiler vendors are free to define behavior where the standard does not.
Indeed, lack of defined behavior in the standard
enables many different behaviors in the compiler,
which enables compiler vendors to provide options
to handle broken contracts in a way that
suits the needs of the user at the moment.
</p>

<p>
Daniel Garcia suggested that
we could define a condition to throw when it was broken.
This behavior could then be exploited by programmers
calling the function out of contract to generate an exception.
Such a reaction is perverse, but perverse things sometimes happen in real code.
More importantly,
<strong>conditions with defined exception semantics
are not different from a wide contract</strong>.
We should not introduce a new mechanism for what we can already say.
</p>

<p>
At the October 2015 standards meeting,
a suggestion was made that some programs must never stop,
even in the presence of broken contracts.
However, for such critical non-stop software,
other problems presently exist that make the goal difficult to achieve.
Memory access violations from wild pointers,
dereferencing a null pointer, and other core-language
features result in instant termination.
These features all have narrow contracts;
the program is assumed to be well-behaved.
Achieving a non-stop goal requires
either a proof of correctness,
or a program that consists of only wide contracts.
The standard library provides neither.
With contracts though,
the standard library could provide assurance through rigourous testing.
In any case,
requiring broken contracts to not terminate the program
does not solve enough of the problem to justify its definition.
Instead, programmers should rely on compiler-defined behavior
in engineering their programs.
</p>


<h3><a name="Identity">Conditions on Object Identity</a></h3>

<p>
We know we get a non-null pointer from <code>c_str</code>.
</p>
<pre class="example">
<code>const charT* basic_string::c_str()
  postcondition { result != nullptr; };</code>
</pre>

<p>
However, the relationship of that pointer to extant objects in the program
is important.
The standard's <code>c_str</code> postcondition describes that relationship.
(There may be a better way to say this postcondition,
but it is the standard's approach.)
</p>
<pre class="example">
<code>const charT* basic_string::c_str()
  postcondition { result != nullptr;
                  for ( size_type i = 0; i &lt;= this-&gt;size(); ++i )
                     p+i == &amp;this-&gt;operator[](i); };</code>
</pre>
<p>
So, <strong>conditions can say when two objects are the same</strong>.
</p>

<p>
Just as importantly,
we can
<strong>use conditions on object identity to disallow aliasing</strong>.
For example, we can disallow self-assignment.
</p>
<pre class="example">
T&amp; operator=(const T&amp; arg)
  precondition { &amp;arg != this; };
</pre>

<p>
The <code>memcpy</code> function is a more complex example of aliasing.
</p>
<pre class="example">
void* memcpy(void* dst, const void* src, size_t len)
  precondition { (const char*)dst + len &lt; (const char*)src ||
                 (const char*)src + len &lt; (const char*)dst; );
</pre>


<h3><a name="State">Conditions on Object State</a></h3>

<p>
The domain of a computation can include the state of an object it accesses.
To avoid leaking implementation artifacts into the contract,
only public functions should appear in a precondition.
</p>
<pre class="example">
<code>T&amp; deque::front()
  precondition { this->size() &gt; 0; };</code>
</pre>

<p>
Likewise, one must be able to assert state in the postcondition.
</p>
<pre class="example">
<code>T&amp; deque::push_front(const T&amp; x)
  postcondition { this->size() &gt; 0; };</code>
</pre>

<p>
An important implication of this approach
is that
<strong>abstraction designers
must expose enough public state-querying functions
to define the contract
and to enable clients to meet the contract</strong>.
</p>


<h3><a name="Invariants">Invariants</a></h3>

<p>
Invariants specify that
a certain state is expected at a given point in the code.
Invariants are helpful in developing and analyzing code.
Loop invariants are helpful in part because
they provide a statement of an inductive step in reasoning.
Furthermore, invariants help drive proofs of correctness
for applications that need a rigorous demonstration of quality.
</p>

<p>
The most widely known invariant mechanism
is the <code>assert</code> macro in C.
The <code>assert</code> macro appears in block scope.
We call this a block-scope invariant.
The primary uses of block-scope invariants
are with respect to the <em>implementation</em> of an abstraction,
rather than to the <em>interface</em> of an abstration.
As such,
<strong>block-scope invariants
are not properly part of the contract</strong>.
However, as the mechanisms and effects are similar,
we consider them part of the same language facility.
</p>

<p>
Despite the above assertion,
John Lakos points out a use for internal invariants in precondition checking.
His example is a search into a sorted array.
The normal precondition would be that the array is sorted.
This would take time linear in the size of the array.
An alternate checking strategy
is to add consistency check into the search procedure itself.
This strategy does not check the entire array;
it only checks that portion of the array that it visits.
This strategy has log complexity,
just as the search itself does,
a substantial savings.
</p>

<p>
Invariants can also appear at class scope.
The main difference is that such invariants
can make claims about the state of a class object between all operations.
The invariants are established on completion of the constructor
and must be valid on entry to the destructor.
The compiler would be responsible for inserting checking code
in all (non-private) functions that might establish, use, or modify the state.
That is, <strong>a class-scope invariant
is the part of a contract that
specifies what it means for an object of the class type
to be well-formed</strong>.
</p>

<p>
Likewise, namespace-scope invariants
specify the state of a namespace-scope variable
between operations on it.
Namespace-scope invariants differ from class-scope invariants
in that they make claims about variables, rather than types.
So, <strong>a namespace-scope invariant
is the part of a contract that
specifies what it means for a namespace-scope variable
to be properly used</strong>.
</p>


<h3><a name="Exceptions">Contracts and Exceptions</a></h3>

<p>
The specification of behavior when exceptions occur within contract evaluation
would be extremely difficult to get right.
Moreover, they would likely be difficult to understand.
So,
<strong>an exception within contract evaluation breaks the contract</strong>.
An implication is that
<strong>contracts should first test for conditions
that might later lead to exceptions</strong>.
</p>

<p>
When a function throws an exception,
it almost certainly could not do what it was asked to do.
In this case,
the postconditions are unlikely to be met.
So, <strong>an exception from a function call
nullifies the postcondition</strong>.
</p>

<p>
On the other hand, class-scope invariants
apply regardless of the manner of member function exit.
Therefore,
<strong>class-scope invariants
define the minimal meaning of exception safety.</strong>
</p>

<p>
Some operations make stronger exception safety claims.
In particular, they claim that
an exception thrown from a member function
will leave the state of an object unchanged
from its state on function entry.
<strong>If we invalidate postconditions on exceptions,
we appear to have no mechanism to describe strong exception safety.</strong>
</p>


<h3><a name="Inheritance">Inheritance</a></h3>

<p>
In the presence of inheritance,
we need to define the relationship of contracts
between members of an inheritance hierarchy.
</p>

<p>
Consider a class <code>B</code>
with preconditions and postconditions on its member functions.
(For the rest of this section,
we use "...conditions on <code>B</code>"
to mean "...conditions on the member functions of <code>B</code>.)
Now consider a class <code>D</code>
derived from <code>B</code>
and intended to be used in the place of <code>B</code>.
The preconditions on <code>D</code>
can be no stronger than those on <code>B</code>
because clients of <code>B</code>
would have no knowledge of those additional requirements.
The preconditions on <code>D</code>
could be weaker than those on <code>B</code>.
The postconditions on <code>D</code>
can be no weaker than those on <code>B</code>
because clients of <code>B</code>
would have no knowledge of those weaker results.
The postconditions on <code>D</code>
could be stronger than those on <code>B</code>.
</p>

<p>
So, <strong>inherited preconditions only get weaker
while the inherited postconditions and invariants only get stronger</strong>.
Eventually, one gets to an invariant constant function,
which requires no preconditions
and leaves room for a vast number of predicates on a known value.
There is something fundamental here,
but identifying it is left as an exercise for the reader.
</p>


<h2><a name="Expectations">Writing Expectations</a></h2>

<p>
Correctness requires knowing what must be true.
Performance depends only on knowing what is usually true.
We call statements on what is usually true an <dfn>expectation</dfn>.
</p>


<h3><a name="Branches">Optimizing Branches</a></h3>

<p>
When compilers know the common case in a branch,
they can optimize the code to deliver better average-case performance.
Compilers can discover the common case
by instrumenting programs to collect an execution profile.
Unfortunately, programmers resist using such capabilities
because of concerns of
build complexity, build time, and training set fidelity.
</p>

<p>
To avoid profiles,
compiler vendors often provide extensions
to enable programmers to state their expectations about likely program behavior.
The most widely known version is probably <code>__builtin_expect</code>
<a href="#GCC">[GCC]</a>.
Such extensions enable the compiler to optimize for the common case.
</p>

<p>
These extensions are are unique to each compiler,
which inhibits their use to only highly performance-sensitive programs
and which inhibits porting of the resulting code.
A standard syntax would solve both problems.
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4425.pdf">N4425
Generalized Dynamic Assumptions</a>
addresses this concern,
but with no integration with other uses of expressions
to describe program behavior.
</p>


<h3><a name="Algorithms">Selecting Algorithms</a></h3>

<p>
While a standard optimization syntax would be helpful,
it is not the most valuable part of an expectation.
<strong>The primary value in an expectation is in communcating
the intended operating environment of an abstraction.</strong>
For example,
</p>
<pre class="example">
<code>void sort1(vector&lt;int&gt; arg)
  expectation { arg.size() &lt;= 7; };</code>
</pre>
<p>
both tells when use is appropriate
and gives reason to use a bubble sort.
</p>

<p>
Another example is the multiplication of large numbers.
<pre class="example">
<code>bignum multiply1(bignum a, bignum b)
  expectation { (-1<<60) &lt; a &amp;&amp; a &lt; (1<<60);
                (-1<<60) &lt; b &amp;&amp; b &lt; (1<<60); };</code>
<code>bignum multiply2(bignum a, bignum b)
  expectation { a &lt; (-1<<600'000) || (1<<600'000) &lt; a;
                b &lt; (-1<<600'000) || (1<<600'000) &lt; b; };</code>
</pre>
<p>
For <code>multiply1</code>,
the classic multiplication algorithm will likely yield the best performance.
For <code>multiply2</code>,
an algorithm based on the Fast Fourier Transform
will likely yield the best performance.
</p>

<p>
Going further,
one can imagine a profile-based analysis
suggesting alternate functions whose expectations
better match the actual behavior of the program.
</p>

<p>
A consequence of expectations in the function interface,
as opposed to just at block scope,
is that
<strong>expectations are a variant of
preconditions, postconditions and invariants</strong>.
They are not an independent feature.
</p>


<h2><a name="Managing">Managing Contracts</a></h2>

<p>
In correct code,
contracts need not be checked
because the code will meet its conditions.
However, code starts incorrect and is refined to correctness.
One purpose of contract support in the language
is to speed that refinement.
</p>

<h3><a name="Compiling">Compiling Contracts</a></h3>

<p>
At different stages in refinement,
programmers will require different amounts of checking.
During initial stages of development,
programmers will want very aggressive checking
to help them identify errors early and quickly,
even at the cost of substantial compile-time and run-time overhead.
At release,
programmers will want minimal checking,
preferably at very low overhead.
</p>

<p>
Everyone anticipates a set of 'build modes'
to control what is and is not checked.
The issue is who decides what gets checked.
The 'who' implies a 'when'.
The 'what' implies knowledge of the character of conditions.
</p>


<h4><a name="WhoDecides">Who Makes the Decision?</a></h4>

<p>
In deciding on what gets checked,
we must first understand who has responsibility for what.
The implementor of an abstraction
is reponsibile for satisfying the invariants and postconditions
<em>given</em> that the preconditions have been satisfied.
The user of an abstraction
is responsible for satisfying the preconditions
<em>given</em> that the postconditions
of prior computations have been satisfied.
</p>

<p>
If the goal of contracts is to help programmers produce better code,
<strong>the control over checking of a condition
should reside with programmer
who can modify the code leading to that condition</strong>.
That is, implementors of an abstraction
should control checking of invariants and postconditions
while users of an abstraction
should control checking of preconditions.
</p>


<h4><a name="WhenDecide">When is the Decision Made?</a></h4>

<p>
Consider the case of a non-inline, non-template function.
The implementor of the function will compile the function,
which implies that the compiler options
should control the checking of
the invariants and postconditions of the function.
More importantly, it implies that the compiler options
should control the checking of
the preconditions of the other functions called by the function.
</p>

<p>
The easiest way to reach this compilation-control goal
is to adopt a policy where
<strong>precondition evaluation
the responsibility of the calling function</strong>,
and not of the called function.
Doing so means that all conditions
that can be satisfied by modifications the function
are controlled by the compilation of that one function.
</p>


<h4><a name="WhatDecide">What Contracts are Affected?</a></h4>

<p>
The decision on what contracts to evaluate
depends on there characteristics of a contract:
exposure, importance, and cost.
</p>

<dl>

<dt>exposure</dt>
<dd>
<p>
A function in the API of a major component
is more exposed to naive users
than is a function that is only internal to a component.
Being more exposed,
the API function
will induce a desire for more defensive programming,
and hence more aggressive evaluation of preconditions.
</p>

<p>
The exposure of a function is generally obtainable from existing sources,
e.g. scope and escape analysis,
and so the contract characterization mechanism
need not provide any information on it. 
</p>
</dd>

<dt>importance</dt>
<dd>
<p>
In a sense, all conditions are important
because violation of any of them may lead to undefined behavior.
However, in practice,
some conditions are more likely to catch errors.
Of course, if a condition never catches errors,
it is implied by another condition and is ineffective.
Furthermore,
some conditions are more likely to lead to permanent data corruption.
John Lakos gave an example of writing a bad date to a database.
Once corrupt data enters the database,
it is extremely hard to identify and correct.
So, we need a mechanism to characterize the importance of a condition.
</p>
</dd>

<dt>cost</dt>
<dd>
<p>
Evaluating a condition has a cost.
The primary factor in the cost is its computational complexity.
This complexity is difficult for the compiler to discern,
and so we need a mechanism to characterize it.
</p>

<p>
The importance of a condition is theoretically independent of its cost.
However, if a condition is critical, its cost is moot.
Even so, programmers would be well-advised to keep critical conditions cheap.
</p>
</dd>
</dl>

<p>
So, <strong>a contract mechanism should characterize conditions
by importance and cost</strong>.
</p>

<p>
In practice,
compilation of contracts will driven by compiler options.
Those options may consider factors other than
those provided directly in the characterization mechanism,
which enables more nuanced management
while keeping the characterization mechanism simple.
</p>


<h3><a name="Characterizing">Characterizing Contracts</a></h3>

<p>
The above discussion will doubtless cause concern
over the complexity of characterizing contracts.
A mechanism that is too complex will not gain support.
A mechanism that is too simple will not solve the problem.
Moreover, we must keep in mind that
ambiguity from a 'simple' mechanism
may well introduce more complexity in practice
because
different programmers will use the same mechanism for different purposes.
</p>

<p>
We can avoid substantial complexity
by ensuring that the contract characterization mechanism
is a description of data, not policy or intended use.
</p>


<h4><a name="Importance">Importance</a></h4>

<p>
Some conditions will be 'critical',
and we can expect them to evaluated
even in performance-sensitive code.
Some conditions are 'effective' in debugging
but are unlikely to have significant consequences
if they are not met in production.
Somewhere in the middle are conditions that are just 'important'.
</p>

<p>
We can probably simplify the importance of a condition to 'critical or not'.
</p>


<h4><a name="Cost">Cost</a></h4>

<p>
Evaluating a condition has a cost.
There are at least two approaches to describing that cost,
each leading to several different descriptions.
</p>

<blockquote>
<dl>
<dt>What is the absolute cost
of the condition relative to machine instructions?</dt>
<dd>
<ol>
<li>constant complexity word operations</li>
<li>constant complexity function calls</li>
<li>log complexity queries on data structures</li>
<li>linear complexity on 'small' parameters, e.g. string comparison</li>
<li>linear complexity on data structures</li>
<li>linear-log complexity on data structures</li>
<li>polynomial complexity on data structures</li>
<li>exponential complexity on data structures</li>
</ol>
</dd>

<dt>What is the cost of the condition relative to the function?</dt>
<dd>
<ol>
<li>less complex than the function</li>
<li>equally complex as the function</li>
<li>more complex than the function</li>
</ol>
</dd>
</dl>
</blockquote>

<p>
We can combine the two approaches.
We can also simplify the cost of a condition
to cases where
its effect on overall execution is significant.
</p>

<ol>
<li>constant complexity</li>
<li>equally or less complex than the function</li>
<li>more complex than the function</li>
</ol>


<h4><a name="Simplified">Combined and Simplified</a></h4>

<p>
Given the above discussion,
consider the following mutually exclusive
contract characterizations of a condition.
</p>

<blockquote>
<dl>

<dt>critical importance</dt>
<dd>
<p>
The programmer of a function decides when a condition is critical.
E.g. John Lakos's example of a function writing ill-formed data to files.
</p>
</dd>

<dt>constant complexity</dt>
<dd>
<p>
The condition has constant complexity,
e.g. primitive operations or very short string comparisons.
Evaluating such conditions will have the least impact on execution time.
</p>
</dd>

<dt>no more complex</dt>
<dd>
<p>
The condition is no more complex than the function itself.
Evaluating such conditions
will not increase the complexity of the program as a whole.
</p>
</dd>

<dt>more complex</dt>
<dd>
<p>
The condition is more complex than the function itself.
Evaluating such conditions
will increase the complexity of the program as a whole.
</p>
</dd>

</dl>
</blockquote>

<p>
Note that these characterizations do not imply a build mode.
However, they do have an order of selection
that serves as data in the build mode.
</p>


<h3><a name="Adopting">Adopting Contracts</a></h3>

<p>
Once C++ supports contracts,
we can expect programmers to adopt contracts into working programs. 
</p>

<p>
Adopting contracts into a program is an incremental process.
Therefore the addition of a contract should
not have ripple effects through the program,
as 'const poisoning' did in the past.
Therefore,
<strong>adding a contract should not change type signatures
or noexcept properties</strong>.
</p>

<p>
This statement means either
that preconditions and their handlers must not throw
or that preconditions and handlers can throw only in throwing functions.
The latter statement is not viable
because the programmer that defines a function
does not know what handlers might be employed
and the programmer that installs a handler
does not know all the affected functions.
Therefore,
<strong>the standard most not define behavior
for a condition or handler that throws an exception</strong>.
Compilers may define such behavior,
but exploiting that behavior should be used for specific purposes
and should not be considered generally portable.
</p>

<p>
We can exploit compiler-defined behavior
for <a href="#Broken">broken contracts</a>
when adopting contracts into a working program.
The steps for adoption are as follows.
Not all portions of a program need be at the same step.
<p>

<dl>
<dt>writing</dt>
<dd><p>
Enable syntax checking of contracts
but otherwise produce code exactly as if contracts where not present.
The program behaves exactly as it did before contracts.
This step enables initial coding and review.
</p></dd>

<dt>logging</dt>
<dd><p>
Enable the evaluation of a contracts.
When a contract is broken,
execute a handler that logs the violation and then returns.
Non-contract code remains exactly as if contracts where not present.
The program behaves exactly as it did before contracts,
except for the logging stream.
This step enables identifying portions of the program
that are out of contract and need fixing.
John Lakos suggested this step.
</p></dd>

<dt>terminating</dt>
<dd><p>
Enable the evaluation of a contracts.
When a contract is broken,
execute a handler that terminates the program,
e.g. with <code>quick_exit</code>.
Non-contract code remains exactly as if contracts where not present.
The program behaves exactly as it did before contracts,
except for termination.
This step enables prevention of
bad data being written to databases and the like.
</p></dd>

<dt>exploiting</dt>
<dd><p>
Use unevaluated contracts
as additional information in the optimization process.
This step enables faster execution of known-good programs.
</p></dd>
</dl>

<p>
In order for adoption to be reasonable,
<strong>compilers must have options that control the extent to which
they interpret and exploit contracts</strong>.
In particular,
compilers need to refrain from exploiting contracts
for optimization unless explicitly told to do so.
</p>


<h3><a name="Testing">Testing Contracts</a></h3>

<p>
How do we know contracts are properly specified?
The first step is a thorough code review.
The next step is testing.
That is, we purposefully write code that
violates the intended contract
to see if the coded contract detects the violation.
Again, this idea comes from John Lakos.
</p>

<p>
How do you test a behavior that leads to standard-undefined behavior?
</p>
<ul>
<li><p>
Rely on compiler-defined behavior.
As with <a href="#Adopting">Adopting Contracts</a>,
we rely on a compiler that evaluates contracts
and calls a handler,
but otherwise does not alter the code generated.
</p></li>
<li><p>
Rely on the nature of contract tests being shallow.
This leads to two possible approaches.
<ul>
<li>
Install a handler that does a long jump back to the test harness.
Because the function under test is immediately beneath the harness,
there is little opportunity for lost memory allocations
between setting the long jump buffer and the jump itself.
</li>
<li>
Install a handler that throws an exception that caught in the harness.
Again, there is little opportunity for losing memory allocations.
However, the test must be compiled with an option
that handles noexcept functions in the same way it would a throwing function.
</li>
</ul>
</li>
</ul>

<p>
Whatever approach is taken,
<strong>the test engineer needs a cooperative compiler</strong>.
</p>


<h3><a name="Handlers">Managing Handlers</a></h3>

<p>
In the above discussion, we have described several different kinds of handlers.
The question is when and how are these installed.
Gabriel dos Reis shared Microsoft's view
that handlers needed to be defined at compile time
in order to prevent security problems with
dynamically installed handlers.
Note that
<strong>compile-time handlers makes the effect of a broken contract
an attribute of the translation unit</strong>.
</p>

<p>
Static handlers do not preclude dynamic handlers,
as a static handler could call through a function pointer
to a dynamically selected handler.
However, in order for programmers setting the dynamic handler
to reach all translation units that accept a dynamic handler,
<strong>the dynamic handler must be standard</strong>.
</p>

<p>
Given several possible kinds of handlers,
should there be a default?
If so, what should it be?
In the absence of any knowledge of the program development environment,
the default should be to terminate the program quickly but safely.
The mechanism for that termination is <code>quick_exit</code>.
</p>


<h2><a name="Implementing">Implementing Contracts</a></h2>

<p>
The two main issues in implementing contracts
are effective dynamic evaluation
and effective static evaluation.
</p>


<h3><a name="DynamicEval">Dynamic Evaluation</a></h3>

<p>
As discussed earlier,
the primary implementation method
is to evaluate any preconditions in the caller.
However, that approach has two problems.
</p>

<ul>

<li><p>
For indirect calls,
the caller does not know the callee
and hence does not know the preconditions
and hence cannot evaluate the preconditions.
(We could potentially make conditions part of the type system,
but doing so would be a substantial breaking change.)
</p></li>

<li><p>
The evaluation of preconditions at call sites
may substantially increase the size of the code
due to code duplication.
</p></li>

</ul>

<p>
Both problems are solved
by providing multiple wrapper functions
corresponding to the level of condition evaluation.
</p>

<ul>
<li>evaluates the 'default' level of preconditions</li>
<li>evaluates all preconditions</li>
<li>evaluates critical preconditions
and those not more complex than the function</li>
<li>evaluates critical preconditions and those with constant complexity</li>
<li>evaluates only critical preconditions</li>
<li>evaluates no preconditions</li>
</ul>

<p>
The first wrapper would constitute the address of the function,
and would be used for all indirect calls.
The last wrapper would be used
when the compiler chooses to evaluate the preconditions at the call site
or when conditions are completely turned off at the call site.
The other wrappers could be used with different compiler options.
</p>

<p>
It is important to note that
<strong>these wrappers
become part of the C++ Application Binary Interface (ABI)</strong>.
The C++ committee and the compiler vendors
need to have confidence that
the contract management descriptions are useful and stable.
</p>

<p>
Note that
this discussion omits the distinction between conditions and expectations.
Since evaluating the latter
essentially require maintaining execution statistics,
it is likely that such evaluation will be conducted
in conjunction with execution profiles,
and hence should not affect the interfaces above.
</p>


<h3><a name="StaticEval">Static Evaluation</a></h3>

<p>
Compilers routinely evaluate expressions with constant arguments.
That technology applies readily to conditions.
</p>

<p>
Some compilers can use some expressions known to be true
to inform the interpretation of subsequent expressions.
However, we cannot say that such an ability
is widely deployed or robust.
However, any contract feature
must enable the gradual evolution of compiler ability.
So, it should neither require nor exclude expression propogation.
</p>


<h2><a name="References">References</a></h2>

<dl>

<dt><a name="GCC">[GCC]</a></dt>
<dd>
A GNU Manual,
6.58 Other Built-in Functions Provided by GCC,
<a href="http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html">
http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html</a>
</dd>

<dt><a name="IEEE">[IEEE]</a></dt>
<dd>
IEEE Standard for Floating-Point Arithmetic,
IEEE Std 754-2008,
<a href="http://ieeexplore.ieee.org/xpl/mostRecentIssue.jsp?punumber=4610933">
http://ieeexplore.ieee.org/xpl/mostRecentIssue.jsp?punumber=4610933</a>
</dd>

</dl>

<h2><a name="Bibliography">Bibliography</a></h2>

<p>
Within this bibliography,
entries marked with an asterisk indicate
papers with a substantial survey component.
</p>

<dl>

<dt>Ottosen</dt>

<dd>
* Proposal to add Design by Contract to C++
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2004/n1613.pdf">N1613</a>
</dd>

<dt>Ottosen, Crowl, Widman</dt>

<dd>
Proposal to add Contract Programming to C++
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2004/n1669.html">N1669</a>
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1773.html">N1773</a>
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1866.html">N1866</a>
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1962.html">N1962</a>
</dd>
<dd>
Contract Programming for C++0x
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1800.pdf">N1800</a>
</dd>

<dt>Meredith</dt>

<dd>
Addressing Exception Specifications for Next Generation of C++
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1825.htm">N1825</a>
</dd>

<dt>Crowl, Ottosen</dt>

<dd>
Synergies between Contract Programming, Concepts and Static Assertions
<a href="http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1867.html">N1867</a>
</dd>

<dt>Lakos, Zakharov, Beels, Myers</dt>

<dd>
Centralized Defensive-Programming Support for Narrow Contracts
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3604.pdf">N3604</a>
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3753.pdf">N3753</a>
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3877.pdf">N3877</a>
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3963.pdf">N3963</a>
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3997.pdf">N3997</a>
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4075.pdf">N4075</a>
</dd>

<dd>
Language Support for Runtime Contract Validation
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4135.pdf">N4135</a>
</dd>

<dd>
Language Support for Contract Validation
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4253.pdf">N4253</a>
</dd>

<dd>
Language Support for Contract Assertions
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4378.pdf">N4378</a>

<dd>
FAQ about Contract Assertions
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4379.pdf">N4379</a>
</dd>

<dt>Garcia</dt>

<dd>
* Exploring the design space of contract specifications in C++
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4110.pdf">N4110</a>
</dd>

<dt>Krauss</dt>

<dd>
Operator <code>assert</code>
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4154.pdf">N4154</a>
</dd>

<dt>Krzemien'ski</dt>

<dd>
* Value constraints
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4160.html">N4160</a>
</dd>

<dt>Meredith</dt>

<dd>
Library Preconditions are a Language Feature
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4248.html">N4248</a>
</dd>

<dt>Garcia</dt>

<dd>
C++ language support for contract programming
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4293.pdf">
N4293</a>
</dd>

<dt>Dos Reis, Lahiri, Logozzo, Ball, Parsons</dt>

<dd>
Contracts for C++: What Are the Choices?
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4319.pdf">N4319</a>
</dd>

<dt>Dos Reis, Garcia, Logozzo, F&auml;hndrich, Lahiri</dt>

<dd>
Simple Contracts for C++
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4415.pdf">N4415</a>
</dd>

<dt>Finkel</dt>

<dd>
Generalized Dynamic Assumptions
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4425.pdf">N4425</a>
</dd>

<dt>Brown</dt>

<dd>
Proposing Contract Attributes
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4435.pdf">N4435</a>
</dd>

</dl>

</body>
</html>
