<!DOCTYPE html>
<html lang="en"><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">

<style>
pre {font-family: "Consolas", "Lucida Console", monospace; margin-left:20pt; }
code {font-family: "Consolas", "Lucida Console", monospace; }
pre > i   { font-family: "Consolas", "Lucida Console", monospace;  font-style:italic; }
code > i  { font-family: "Consolas", "Lucida Console", monospace;  font-style:italic; }
pre > em  { font-family: "Consolas", "Lucida Console", monospace;  font-style:italic; }
code > em { font-family: "Consolas", "Lucida Console", monospace;  font-style:italic; }
dl > dt { font-style:italic; }
body { font-family: "Calibri" }

@media (prefers-color-scheme: dark) {
	body { background: #111; color:  #ccc; }
	a { color:  #38f; }
	a:visited { color:  #a4d; }
	.sect { color:  #ccc; }
}

@media (prefers-color-scheme: light) {
	body { background:  white; color: black; }
}

del { text-decoration: line-through; color: #8B0040; }
ins { text-decoration: underline; color: #005100; }

p.example   { margin-left: 2em; }
pre.example { margin-left: 2em; }
div.example { margin-left: 2em; }
div.poll { margin-left: 2em; }

code.extract { background-color: #F5F6A2; }
pre.extract  { margin-left: 2em; background-color: #F5F6A2;  border: 1px solid #E1E28E; }

p.function    { }
.attribute    { margin-left: 2em; }
.attribute dt { float: left; font-style: italic;  padding-right: 1ex; }
.attribute dd { margin-left: 0em; }

.editor { color: #4444BB; font-style: normal; background-color: #DDDDDD; }

tab { padding-left: 4em; }
tab3 { padding-left: 3em; }

.link { float: right; font-family: "Consolas", "Lucida Console", monospace; font-size:80% }

blockquote.std    { color: #000000; background-color: #F1F1F1;  border: 1px solid #D1D1D1;  padding-left: 0.5em; padding-right: 0.5em; }
blockquote.stddel { text-decoration: line-through;  color: #000000; background-color: #FFEBFF;  border: 1px solid #ECD7EC;  padding-left: 0.5em; padding-right: 0.5em; ; }
blockquote.stdins { text-decoration: underline;  color: #000000; background-color: #C8FFC8;  border: 1px solid #B3EBB3; padding: 0.5em; }
table.header { border: 0px; border-spacing: 0;  margin-left: 0px; font-style: normal; }
table.poll { border: 1px solid black; border-spacing: 0px;  margin-left: 0px; font-style: normal; }
table { border: 1px solid black; border-spacing: 0px;  margin-left: auto; margin-right: auto; }
th { text-align: left; vertical-align: top;  padding-left: 0.4em; border: none;  padding-right: 0.4em; border: none; }
td { text-align: left;  padding-left: 0.4em; border: none;  padding-right: 0.4em; border: none; }

.revision   { /*color: #005599;*/ }
.grammar { list-style-type:none }

</style>

<title>Contract support &mdash; Record of SG21 consensus</title>

</head>
<body>

<table class="header"><tbody>
  <tr>
    <th>Document number:&nbsp;&nbsp;</th><th> </th><td>P2521R5</td>
  </tr>
  <tr>
    <th>Date:&nbsp;&nbsp;</th><th> </th><td>2023-08-15</td>
  </tr>
  <tr>
    <th>Audience:&nbsp;&nbsp;</th><th> </th><td>SG21</td>
  </tr>
  <tr>
    <th>Reply-to:&nbsp;&nbsp;</th><th> </th><td>
        <address>Andrzej Krzemieński &lt;akrzemi1 at gmail dot com&gt;</address>
        <address>Gašper Ažman &lt;gasper dot azman at gmail dot com&gt;</address>
        <address>Joshua Berne &lt;jberne4 at bloomberg dot net&gt;</address>
        <address>Bronek Kozicki &lt;brok at spamcop dot net&gt;</address>       
        <address>Ryan McDougall &lt;mcdougall dot ryan at gmail dot com&gt;</address>
        <address>Caleb Sunstrum &lt;caleb dot sunstrum at gmail dot com&gt;</address>
      </td>
  </tr>
</tbody></table>



<h1>Contract support &mdash; Record of SG21 consensus</h1>


<p> The goal of this paper is to track the decisions of SG21 on controversial 
    decisions regarding the Contracts MVP. Nothing is proposed in this document.
    It is meant to be used as a reference for when which decision was made an
    how the current shape of contract support is different from "C++20 contracts"
    (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0542r5.html"
           title="G. Dos Reis, J. D. Garcia, J. Lakos, A. Meredith, N. Myers, B. Stroustrup, &ldquo;Support for contract based programming in C++&rdquo;"
           >[P0542R5]</a>) or the original "Contracts MVP" 
    (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2388r4.html"
        title="Andrzej Krzemieński, Gašper Ažman, &ldquo;Minimum Contract Support: either No_eval or Eval_and_abort&rdquo;"
        >[P2388R4]</a>).
    
    It proposes nothing that hasn't
    already been described in either 
    <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2388r4.html">[P2388R4]</a> or
    <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2461r1.pdf">[P2461R1]</a>.
    Nor is it a comprehensive description of the current shape of the Contracts MVP.
    The full proposal is expected to be tracked in the revisions of 
    <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2388r4.html"
        title="Andrzej Krzemieński, Gašper Ažman, &ldquo;Minimum Contract Support: either No_eval or Eval_and_abort&rdquo;"
        >[P2388R4]</a>.




<h2><a class="sect" id="rev">0. Revision history <span class="link">{rev}</span></a></h2>



<h3><a class="sect" id="rev.r01">0.1. R0 → R1<span class="link">{rev.r01}</span></a></h3>

<ol>
  <li>We now disallow contract annotations on function re-declarations and overriding function declarations.</li>
	<li>Clarified what happens when a contract predicate contains a call to a virtual function.</li>
	<li>Included poll results on including postconditions in the MVP.</li>
	<li>Explained why we need mixed translation modes to be implementation-defined.</li>
	<li>Removed the text which suggested that implementing runtime precondition checks inside function bodies is a necessity.</li>
	<li>Described more special cases related to virtual functions: when a base class is a template parameter, and when 
	    a function overrides more than one virtual function.</li>
	<li>Clarified that we are aiming at freestanding implementations.</li>
	<li>No longer defining look-up in contract annotations by analogy with <code>noexcept</code>.</li>
	<li>Mixing translation modes is IFNDR.</li>
</ol>


<h3><a class="sect" id="rev.r02">0.2. R1 → R2<span class="link">{rev.r02}</span></a></h3>

<ol>
  <li>Described the proposed evaluation order of preconditions and postconditions. See section <a href="#pro.ord">{pro.ord}</a>.</li>
	<li>Non-reference function parameters named in the postcondition must be declared <code>const</code>. See section <a href="#pro.arg">{pro.arg}</a>.</li>
	<li>Explained why reading the value of function arguments instead of function parameters cannot solve the problem of non-reference function parameters 
      referenced in postconditions. See section <a href="#pro.arg.out">{pro.arg.out}</a>.</li>
	<li>Changed the motivation for adding side effect removal: it is not efficiency, it is the intention to discourage programmers
	    from deliberately putting side effects in contract annotations.</li>
</ol>


<h3><a class="sect" id="rev.r03">0.3. R2 → R3<span class="link">{rev.r03}</span></a></h3>

<ol>
    <li>Changed the title of the paper to better reflect the idea: keeping track of SG21 consensus
        and outstanding controversial issues.
        </li>
    <li>Updated with decisions from the Issaquah 2023 meeting. Side effects are allowed and can be removed 
        or duplicated in <em>Eval_and_abort</em> mode. See section <a href="#pro.eff">{pro.eff}</a>.
        </li>
	<li>Added a new controversial issue: throwing from a contract predicate.</li>

</ol>


<h3><a class="sect" id="rev.r04">0.4. R3 → R4<span class="link">{rev.r04}</span></a></h3>

<ol>
	<li>A bug has been found in how we override multiple virtual functions
        with different contract annotations. This is now tracked as an open item in <a href="#pro.2bs">{pro.2bs}</a>.</li>
    <li>Translation modes have been dropped. Instead, for each evaluation of each contract predicate it is 
        implementation-defined what happens. See section <a href="#pro.ieo">{pro.ieo}</a>.</li>
    <li>We now specify what happens for predicates that finish in an unusual way, 
        such as <code>longjmp</code>. See <a href="#pro.mbp">{pro.mbp}</a>.
        </li>
    <li>Specified the semantics for contract violation handler. See section <a href="#pro.hnd">{pro.hnd}</a>.  
        </li>
    <li>Specified the semantics for throwing predicates. See section <a href="#pro.tfp">{pro.tfp}</a>.
        </li>
    <li>Added open issue for contract annotations on trivial functions. See section  <a href="#con.trv">{con.trv}</a>.</li>
</ol>


<h3><a class="sect" id="rev.r05">0.5. R4 → R5<span class="link">{rev.r05}</span></a></h3>

<ol>
	<li>An overriding function cannot declare a precondition or a postcondition but when invoked, the pre-/post-conditions
	    from the overridden function apply. See section <a href="#pro.2bs">{pro.2bs}</a></li>
    <li>Shortened the discussion on the choice of syntax.</li>
    <li>Updated the list of unresolved issues in section <a href="#con">{con}</a>.</li>	
</ol>

<!-- <a href="https://isocpp.org/files/papers/P2877R0.pdf"
           title="Joshua Berne, Tom Honermann, &ldquo;Contract Build Modes, Semantics, and Implementation Strategies&rdquo;">[P2877R0]</a> -->

<h2><a class="sect" id="mot">1. Motivation <span class="link">{mot}</span></a></h2>



<p> The motivation for adding contract support framework to C++ is to enable the programmers to define in a formal way what constitutes
    a contact violation (and therefore a bug) in their programs. This information can be later used by different tools to perform
    static or dynamic analysis of the program, add instrumentation code, or generate documentation or programmer hints in the IDE.
		It has been described in more detail in <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2388r4.html">[P2388R4]</a>.
		We want contracts to be available in freestanding implementations.</p>

<p> The motivation for producing this paper is to focus on documenting the consensus of SG21.<p>



<h2><a class="sect" id="not">2. Notation <span class="link">{not}</span></a></h2>

<p>Because the choice of syntax for contract annotations has no consensus yet, in this paper we use placeholder notation:</p>

<pre>
int select(int i, int j)
  PRE(i &gt;= 0)               <em>// precondition</em>
  PRE(j &gt;= 0)
  POST(r: r &gt;= 0)           <em>// postcondition; r names the return value</em>
{
  ASSERT(_state &gt;= 0);      <em>// assertion; not necessarily an expression</em>

  if (_state == 0) return i;
  else             return j;
}
</pre> 


<h2><a class="sect" id="pro">3. Proposed characteristics <span class="link">{pro}</span></a></h2>


<h3><a class="sect" id="pro.tri">3.1. Three declarations: preconditions, postconditions and assertions<span class="link">{pro.tri}</span></a></h3>

<p>We propose that all three types of declarations are included in the minimum contract support:</p>

<ol>
<li>Preconditions.</li>
<li>Postconditions.</li>
<li>Assertions.</li>
</ol>

<p>Although it is possible to add only preconditions to the language and gain some benefit, we believe that only the three components
   added together bring sufficient value to warrant the modification of the language. We also believe that the syntax and semantics of preconditions
   must be compatible with these of the postconditions. So even if the preconditions were to be added in isolation, we would have to
   have a polished design for postconditions. This means that preconditions are blocked on the postcondition design even for the "only preconditions" variant.
   </p>

 
<p>Poll 1 (2021-12-14)</p>

<div class="poll">
<p>Postconditions should be in the MVP at this time.</p>

<table class="poll">
<tr><td>SF</td><td>F</td><td>N</td><td>A</td><td>SA</td></tr>
<tr><td>1</td><td>7</td><td>3</td><td>4</td><td>1</td></tr>
</table>

<p>Marginal consensus (if at all).</p>
</div>



<h3><a class="sect" id="pro.mod">3.2. No translation modes<span class="link">{pro.mod}</span></a></h3>


<p> The initial version of Contracts MVP proposed two modes that a translation unit can be translated in:</p>

<ol>
  <li><strong><em>No_eval</em></strong>: compiler checks the validity of expressions in contract annotations,
      but the annotations have no effect on the generated binary. Functions appearing in the predicate are odr-used.
      </li>
  <li><strong><em>Eval_and_abort</em></strong>: each contract annotation is checked at runtime.
      The check evaluates the corresponding predicate; if the result equals <code>false</code>,
      the program is stopped an error return value.
      </li>
</ol>

<p> The goal was to reduce the need for too many compiler switches, as was the case for 
    <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0542r5.html"
       title="G. Dos Reis, J. D. Garcia, J. Lakos, A. Meredith, N. Myers, B. Stroustrup, &ldquo;Support for contract based programming in C++&rdquo;"
       >[P0542R5]</a>, on the one hand, but to still reflect the fact that different
    behaviors can result from the same contract annotation in different compilations.
    
<p> This is no longer the case there are no modes <em>No_eval</em> or <em>Eval_and_abort</em>.
    The current state is described in <a href="#pro.ieo">{pro.ieo}</a>.



<h3><a class="sect" id="pro.ord">3.3. Evaluation order<span class="link">{pro.ord}</span></a></h3>

<p> We propose the following evaluation order for preconditions and postconditions when a function is invoked. </p>

<ol>
<li>Function parameters are initialized.</li>
<li>Preconditions are evaluated.</li>
<li>Evaluation of the function body begins. (This includes constructor initialization list, function-try-block.)</li>
<li>The return value, if any, is produced, creating an object in the caller or through the temporary materialization. </li>
<li>The destructors of automatic objects are called.</li>
<li>The postconditions are evaluated. (The postcondition can already see the returned object, and still see the function parameters.)</li>
<li>The destructors of function parameters are called.</li>
</ol> 

<p> In this proposal throwing from the contract predicate triggers a call to <code>std::terminate()</code>, 
    therefore there is no way to observe whether preconditions and postconditions are called inside or outside the function.
    </p>		


<h3><a class="sect" id="pro.lok">3.4. Name look-up<span class="link">{pro.lok}</span></a></h3>

<p> We propose that names referred in preconditions and postconditions are looked up as if they appeared 
    in a <code>decltype</code> in a <em>trailing-return-type</em>,
    if the function had one. In particular, this means that private members can appear in pre/post-conditions.</p>
		
<p> Programming guidelines often recommend that in contract predicates of public member
    functions one should only use the public interface of the class. This is to enable the user of the class 
		to check the precondition in case the object state is not known. However, this is only a guideline, and enforcing it in the language
    would break other use cases that do not subscribe to the above advice. Also,
		precondition checks on member functions may be impossible to write using the public interface of the class
		because the contracts of the accessors might lead to recursive contract checks even when accessors themselves are not recursive.
    </p>

<p> In general, the users must <em>ensure</em> that the precondition of the called function is satisfied.
    If they do that, they do not have to check the precondition.
    </p>

<p> Allowing the access to protected and private members enables a practical usage scheme.
    In general, function precondition is something that cannot be fully expressed as C++ expression.
    The implementers choose how much of the function precondition they want to check. They may choose
    to check some parts of the precondition by accessing private members that they do not want
    to expose to the users, for instance, because the private implementation may change over time
    or under configuration:
    </p>

<pre>class callback
{
#if !defined NDEBUG
  mutable int _call_count = 0;
#endif

  <em>// ...</em>

public:
  void operator() const
    <em>// real contract: this function can be called no more than 8 times,</em>
    <em>// so the precondition is that the function has been called 7 or less times</em>

#if !defined NDEBUG
    <em>// attempt to check the precondition</em>
    PRE(_call_count &lt;= 7);
#endif
};</pre>

<p> In the above example, the precondition can only be checked in debugging mode.
    Once <code>NDEBUG</code> is defined, member <code>_call_count</code> is removed
    and there is no way to test the precondition.
    </p>

<p> Also, a hypothetical constraint to use only public members in contract predicates
    could result in programmers turning their private and protected members into public
    members only to be able to express the pre- and postconditions, which does not
    sound like a good class design.

</p><p> This has been described in detail in
    <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1289r1.pdf">[P1289R1]</a>,
    and in fact adopted by EWG. </p>
		


<h3><a class="sect" id="pro.ret">3.5. Naming the return value <span class="link">{pro.ret}</span></a></h3>

<p> It is possible to name the return value (or reference) in the postcondition, except for one situation: 
    when we use a return placeholder type and do not provide the definition from which the type could be deduced:</p>
		
<pre>auto get_digit()
  POST(c: is_digit(c)); <em>// error: decltype(c) unknown</em>
</pre>	

<p> This has been discussed in detail in
    <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1323r2.html">[P1323R2]</a>.
    </p>	
		

<h3><a class="sect" id="pro.ptr">3.6. Indirect function calls
        <span class="link">{pro.ptr}</span></a></h3>


<p> Function pointers and references cannot have contract annotations,
    but functions with contract annotations can be assigned to them:</p>

<pre>using fpa = int(*)(int) PRE(true); <em>// error</em>

using fptr = int(*)(int);
int f(int i) PRE(i &gt;= 0);

fptr fp = f;  <em>// OK</em>
fp(1);        <em>// precondition is checked in Eval_and_abort mode</em>
</pre>

<p> In other words, contract annotations are not part of function type.
    This allows dynamically selecting behavior at runtime based on inputs.
    </p>

<pre>int fast(int i) PRE(i &gt; 0);  <em>// fast, but has a narrow contract</em>
int slow(int i) PRE(true);   <em>// wide contract, but slow</em>

int f(int i)
{
  int (*fp) (int) = i &gt; 0 ? fast : slow;
  return fp(i);   <em>// if fast() is called, its precondition is checked</em>
}
</pre>

<p> The consequence of allowing this behavior is that an implementation
    cannot check the precondition at the call site for indirect calls. 
		The check has to be performed either inside the function or in a thunk.</p>

<p> We propose the same behavior, for the same reasons, for function wrappers:</p>

<pre>
using fp = int(*)(int);
int f(int i) PRE(i &gt;= 0);

function&lt;int(int)&gt; fp = f;  <em>// OK</em>
fp(1);   <em>// precondition is checked in Eval_and_abort mode</em>
</pre>
	
	
<h3><a class="sect" id="pro.vir">3.7. Virtual functions
        <span class="link">{pro.vir}</span></a></h3>

<p> Contract annotations may appear in virtual member function declarations,
    but only in non-overriding functions. 
    When a virtual function is overridden, the overriding function has implicitly the
    same set of preconditions and postconditions as the overridden function,
    the program is ill-formed if you try to declare contract annotations in the 
		overriding function explicitly, even if they look identical to the ones in the overridden function.
		</p>

<pre>
struct Base {
  virtual void f() PRE(p1());   <em>// ok: introducing the precondition</em>
};

struct Deriv1 : Base {
  void f() override;            <em>// ok: Deriv1::f has precondition p1()</em>
};

struct Deriv2 : Base {
  void f() override PRE(p1());  <em>// error: Deriv2::f has the precondition redeclared</em>
};

struct Deriv3 : Base {
  void f() override PRE(p2());  <em>// error: Deriv3::f has different precondition than Base</em>
};
</pre>
		
<p> The overriding function has the same contract annotations as the virtual function in the base
    class, and the names in the predicates are looked up in the context of the
    base class.</p>

<pre>
static const int N = 1; <em>// #1</em>

struct Base
{
  virtual void f() PRE(N == 1);
};

template &lt;int N&gt;       <em>// global N is shadowed</em>
struct Deriv : Base
{
  void f() override;
};

int main()
{
  Deriv&lt;2&gt;{}.f(); <em>// precondition test passes</em>
}
</pre>

<p> The precondition in the overriding function is <code>N == 1</code>,
    but the name lookup is performed in the context of class <code>Base</code>,
    so it sees the global variable <code>N</code> declared in line #1.</p>

<p> When the overriding function is called in a "non-virtual" context (as in the above example), 
    the pre-/post-conditions from the overridden function still apply.
    </p>
		
<p> If a predicate in the contract annotation of function <code>f</code> contains a call to a virtual function,
    the virtual function call is resolved as if the function was called inside function <code>f</code>:</p>

<pre>
struct Window 
{
  Window() POST(isClosed());
  virtual bool isClosed() const;
  virtual void open() PRE(isClosed());
}; 

struct SpecialWindow : Window
{
  bool isClosed() const override;
  void open() override;
};

int main()
{
  SpecialWindow w {}; <em>// calls Window::isClosed(), because virtual function calls are not resolved in constructors </em>
  w.open();           <em>// calls SpecialWindow::isClosed(), because isClosed is virtual</em>
}
</pre>

<p> As a consequence of the above decisions, we do not allow the preconditions in the overriding function to be "wider"
    and the postconditions to be "narrower" than in the overridden function,
    even though this idea &mdash; one aspect of the Liskov Substitution Principle &mdash; is well explored and implemented in other languages.
		The reason for this is that we do not yet have a good understanding of what effect this principle should have on the feature design.
		Should it be just a "best practice" that the programmers are taught? Or should it be enforced by the language? But how?
		We could think of a number of ways. Given the declarations:</p>
		
<pre>
struct Base {
  virtual void f() PRE(p1());
};

struct Deriv : Base {
  void f() override PRE(p2());
};
</pre>

<ol>
<li> Should compiler be able to prove (even if it cannot see the definitions of <code>p1</code> and <code>p2</code>) 
    that the latter is no stricter than the former?</li>
<li> Shall the compiler report an error unless
    the precondition in the overriding function has the form <code>p1() || p2()</code>? </li>
<li> Or should the compiler accept this code and evaluate <code>p1() &amp;&amp; p2()</code> when <code>Deriv::f</code> is called through the <code>Base</code> interface,
     but evaluate predicate <code>p2()</code> when <code>Deriv::f</code> is called directly?     		
</ol>
		
<p>Option 1 is clearly impossible. The other options might be implementable, but it is more like a guess,
    as we know of no implementation experience with these.</p>

<p> However, the decision to add support for this feature can be deferred for later, because the way we specify the feature now
    (ill formed) remains open for future extensions in any of the three directions.
		</p> 


<p> Poll 22 (2023-08-10)</p>

<div class="poll">
<p> For the Contracts MVP, an overriding function shall not specify preconditions 
    or postconditions, and inherits those of the overridden function.</p>

<table class="poll">
<tr><td>SF</td><td>F</td><td>N</td><td>A</td><td>SA</td></tr>
<tr><td>4</td><td>5</td><td>2</td><td>2</td><td>0</td></tr>
</table>
<p>Result: consensus </p>
</div>		


<h4><a class="sect" id="pro.vir.tmp">3.7.1 Class templates
        <span class="link">{pro.vir.tmp}</span></a></h4>
				
<p> The same restrictions for virtual functions apply for class templates, except that compilation errors might be deferred till 
    template instantiation time:</p>
	
<pre>
struct Base1 {
  virtual void f1(int i);
};

struct Base2 {
  virtual void f2(int i);
};

template &lt;typename Base&gt;
struct Deriv : Base {
  void f2(int i) PRE(i &gt; 0); <em>// ok, so far</em>
};

Deriv&lt;Base1&gt; d1 {}; <em>// ok</em>
Deriv&lt;Base2&gt; d2 {}; <em>// compiler error</em>
</pre>	




<h3><a class="sect" id="pro.2bs">3.8. Inheriting multiple contracts
        <span class="link">{pro.2bs}</span></a></h3>

<p> When a function overrides more than one function, neither 
the overriding function nor any of the overridden functions shall specify 
preconditions or postconditions.</p>
	
<pre>
struct Base1 {
  virtual void f(int i) PRE(p());
};

struct Base2 {
  virtual void f(int i) PRE(p()); <em>// same precondition</em>
};

struct Base3 {
  virtual void f(int i);          <em>// no precondition</em>
};

struct Base4 {
  void f(int i);                  <em>// not virtual</em>
};

struct Deriv12 : Base1, Base2 {
  void f(int i) override;    <em>// ill formed</em>
};

struct Deriv13 : Base1, Base3 {
  void f(int i) override;    <em>// ill formed</em>
};

struct Deriv14 : Base1, Base4 {
  void f(int i) override;    <em>// OK: overriding a single fun</em>
};
</pre>



<p> Poll 23 (2023-08-10)</p>

<div class="poll">
<p> For the Contracts MVP, if a function overrides more than one function, neither 
the overriding function nor any of the overridden functions shall specify 
preconditions or postconditions.</p>

<table class="poll">
<tr><td>SF</td><td>F</td><td>N</td><td>A</td><td>SA</td></tr>
<tr><td>6</td><td>7</td><td>0</td><td>1</td><td>0</td></tr>
</table>
<p>Result: consensus </p>
</div>	



	
<h3><a class="sect" id="pro.imm">3.9. Contract annotations and the immediate context
    <span class="link">{pro.imm}</span></a></h3>


<p> In this proposal the predicates in contract annotations are <em>not</em> in the
    immediate context of the function. They behave similarly to exception specification:</p>

<pre>
template &lt;std::regular T&gt;
void f(T v, T u)
  PRE(v &lt; u); <em>// not part of std::regular</em>

template &lt;typename T&gt;
constexpr bool has_f =
  std::regular&lt;T&gt; &amp;&amp;
  requires(T v, T u) { f(v, u); };

static_assert( has_f&lt;std::string&gt;);         <em>// OK: has_f returns true</em>
static_assert(!has_f&lt;std::complex&lt;float&gt;&gt;); <em>// ill-formed: has_f causes hard instantiation error</em>
</pre>


<p> As a consequence, we may have a function template that works well for
    a given type, but stops working the moment we add a contract annotation.
    This also affects how concepts would be taught: a good concept should express
    not only the requirements that are necessary in the <em>implementation</em>
    of the generic algorithms, but also those that are necessary in the
    specification of contract annotations in these algorithms.
    </p>


<h3><a class="sect" id="pro.end">3.10. <code>abort()</code> vs <code>terminate()</code> <span class="link">{pro.end}</span></a></h3>

<p> In this proposal, throwing from the predicate calls <code>std::terminate()</code> while a failed runtime check
    aborts the application even more abruptly: close to calling <code>std::abort()</code>, but we do not require 
		the actual call to <code>std::abort()</code>, as the function may not be present in freestanding. </p>

<p>	We do not require the implementations to allow the users to install custom contract violation handlers, nor do we
    specify any interface describing how this is done. However, we do not actively forbid the implementations form performing some logic,
		as long as it never throws or calls <code>longjmp()</code>. 
		This makes the MVP proposal smaller; but it remains open for the contract violation handler support in the future.
    </p>

<p> The above distinction reflects the fundamental difference between the two situations.
    Throwing from a predicate is analogous to throwing from a noexcept function &mdash; 
		an expected response to an unhandled exception thrown in procedural code &mdash; 
		but it does not signal that the program state itself is corrupt, or that the program has a logic error, which is what a contract violation detects.
		Maybe a comparison
    had to allocate memory, and this allocation failed, because today the server is exceptionally busy. We want to
    handle it the way we usually handle exceptions when there is no suitable handler: <code>std::terminate()</code>
    is an exception handler, with its unique control flow, however harsh.</p>

<p> In contrast, failing a runtime correctness test is an indication of a bug, and it is not clear if <code>std::terminate()</code>,
    which is the second level of exception handling mechanism, is a suitable tool. The call to <code>std::terminate()</code>
    either calls <code>std::abort()</code> or calls a terminate handler installed by the user. In case the contract is
    violated, and we can be sure the program contains a bug, calling a user-installed function may be unsafe,
    and can pose a security risk.</p>

<p> Moreover, <code>std::terminate()</code> is not available in freestanding implementations. </p>


<h3><a class="sect" id="pro.log">3.11. No runtime error message<span class="link">{pro.log}</span></a></h3>

<p> This revision of the paper does not require or encourage
    any error message to be displayed to standard diagnostic stream, or anywhere
    in <em>Eval_and_abort</em> mode.
    There are two reasons. First, there is no standard diagnostic stream on
    freestanding implementations, and we want contract support to be available on
    those platforms. Second, for security reasons. When an application is in a confirmed
    incorrect state, performing IO operations may pose a security risk.
    As the primary focus of this proposal is safety, we choose a conservative
    approach.</p>
		
<p> Note that breaking into a debugger upon contract violation is a valid way to handle these situations,
    as it takes a single instruction and does not depend on program state.</p>
		

<h3><a class="sect" id="pro.dec">3.12. Contract annotations upon the first and subsequent declarations<span class="link">{pro.dec}</span></a></h3>

<p> We require that if a given function <code>f</code> has declared preconditions and postconditions, they shall be visible in the first
    declaration of <code>f</code> in a translation unit (TU): otherwise the program is ill-formed. Subsequent declarations must omit 
    contract annotations. If <code>f</code> is declared in more than one TU,
    the corresponding first declarations of <code>f</code> shall be identical (modulo parameter names): otherwise the program is ill-formed with no
    diagnostic required. As a consequence, the following is illegal:</p>
		
<pre>
int select(int i, int j);  <em>// first declaration</em>
	
int select(int i, int j)   <em>// second declaration</em>
  PRE(i &gt;= 0)              <em>// error: initial decl has no contract annotations</em>
  PRE(j &gt;= 0)
  POST(r: r &gt;= 0); 
</pre>

<p>The following is also illegal</p>

<pre>
int select(int i, int j)  <em>// first declaration</em>
  PRE(i &gt;= 0)
  PRE(j &gt;= 0)
  POST(r: r &gt;= 0);
	
int select(int i, int j)   <em>// second declaration</em>
  PRE(i &gt;= 0)              <em>// error: contract annotations on redeclaration</em>
  PRE(j &gt;= 0)
  POST(r: r &gt;= 0); 
</pre>

<p> The reason for this restriction is implementability issues, similar to those for default function arguments.
    This decision departs from <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0542r5.html">[P0542R5]</a>,
		which allowed putting odr-identical contract annotations on redeclarations. The reason we do not allow contract annotations on
		redeclarations is because this way we avoid the reason to define the notion of being "odr-identical".</p>



<h3><a class="sect" id="pro.arg">3.13. Non-reference parameters mentioned in postconditions must be <code>const</code><span class="link">{pro.arg}</span></a></h3>


<p> If a non-reference function parameter is named in a postcondition, that parameter shall be declared <code>const</code> in every declaration of
    the function.</p> 
		
<pre>
int generate(int lo, int hi)              <em>// error: lo and hi should be declared const</em>
  PRE(lo &lt;= hi)
  POST(r: lo &lt;= r &amp;&amp; r &lt;= hi);
	
int generate(int&amp; lo, const int&amp; hi)      <em>// ok: lo and hi are references</em>
  PRE(lo &lt;= hi)
  POST(r: lo &lt;= r &amp;&amp; r &lt;= hi);
	
int generate(int lo, int hi)              <em>// ok: lo and hi not referenced in a postcondition</em>
  PRE(lo &lt;= hi)
  POST(r: r &gt;= 0);
	
int generate(const int lo, const int hi)  <em>// ok: lo and hi are declared const</em>
  PRE(lo &lt;= hi)
  POST(r: lo &lt;= r &amp;&amp; r &lt;= hi);
</pre>
 
<p> This is to prevent the situation where a contract check would return an answer
    incompatible with the programmer expectations: a false positive or a false negative.
		This problem has been explained in detail in <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2388r4.html">[P2388R4]</a>
    and <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2466r0.html">[P2466R0]</a>.
		Here, we only show an example that demonstrates the issue:</p>
		
<pre><em>// declaration that the user sees:</em>
int generate(int lo, int hi)
  PRE(lo &lt;= hi)
  POST(r: lo &lt;= r &amp;&amp; r &lt;= hi);

<em>// definition that only the author sees:</em>
int generate(int lo, int hi)
{
  int result = lo;
  while (++lo &lt;= hi) <em>// note: lo modified</em>
  {
    if (further())
      ++result;      <em>// incremented slower than lo</em>
  }
  return result;     <em>// at this point result &lt; lo</em>
}

<em>// usage:</em>
int min = 1;
int max = 10;

int r = generate(min, max);   <em>// postcondition check fails</em>
assert(min &lt;= r &amp;&amp; r &lt;= max); <em>// even though this assertion is satisfied</em>
</pre>

<p> How is this problem addressed in other languages?
    In D, this problem has been ignored: postconditions like the one above give false positive or false negative results.
		In ADA this problem does not occur: this is due to the way the function arguments are designed. In ADA, for each 
		function argument, the programmer has to specify if it is IN or OUT or INOUT. The OUT and INOUT parameters correspond to reference
    parameters in C++, so there is no problem here. The IN parameters, on the other hand, are immutable, so there is no question of 
    changing them inside the function: IN parameters correspond to <code>const</code> by-value parameters in C++.
    SG21 decided to follow what ADA does, in the following poll on 2022-03-10.		
</p>	


<p> Poll 2 (2022-03-10)</p>

<div class="poll">
<p> Adopt a change based on option #2 from the paper 
    <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2521r1.html">[P2521R1]</a> section 
    <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2521r1.html#con.arg">4.3</a>: 
    if the postcondition uses a non-reference parameter: require it to be const objects.</p>

<table class="poll">
<tr><td>SF</td><td>F</td><td>N</td><td>A</td><td>SA</td></tr>
<tr><td>5</td><td>6</td><td>0</td><td>1</td><td>0</td></tr>
</table>
<p>Strong consensus </p>
</div>

	
<p> This decision has the following consequences. First, in the MVP contracts, the programmers have the 
    following options when they need their postconditions to refer to non-reference function parameters:</p>
	
<ol>
  <li>Do not reflect this postcondition in a contract annotation. (Do what you do in C++20, put it in a comment...)</li>
	<li>Add the otherwise redundant <code>const</code> qualifier.</li>
</ol>

<p> Second, this implies that once a postcondition starts referencing a non-reference function parameter, 
    the language rules that govern this parameter change: now the additional <code>const</code> qualifier
		makes a difference: programmers can no longer choose to add it or omit it between declarations:
		</p>
		
<pre>
void f(int i) POST(i != 0);       <em>// error: i must be const </em>

void g(const int i) POST(i != 0);
void g(int i) {}                  <em>// error: missing const for i in definition</em>

void h(const int i) POST(i != 0);
void h(const int i) {} 
void h(int i);                    <em>// error: missing const for i in redeclaration</em>
</pre>

<p> This choice guarantees that compiler statically prevents any modifications to these function parameters: both in the function body
    and in the contract predicates: </p>
	
<pre>
void f(const int i) 
  POST(++i != 0)                 <em>// error: cannot mutate a const object</em>
  POST(is_const_v&lt;decltype(i)&gt;); <em>// postcondition satisfied</em>

void f(const int i)
{
  ++i;                           <em>// error: cannot mutate a const object</em>
}	
</pre>

<p> One consequence of this is that you cannot use move-semantics for function parameters referenced in postconditions:</p>
	
<pre>
void f(unique_ptr&lt;int&gt; i) 
  PRE(i)                        <em>// ok (no restrictions for preconditions)</em>
{
  return i;                     <em>// ok: move</em>
}

void g(const unique_ptr&lt;int&gt; i) <em>// const is now required</em> 
  PRE(i)              
  POST(i)
{
  ++*i;
  return i;                     <em>// error: copy constructor inaccessible</em>
}
</pre>

<p> This price is paid even if the programmer uses only <em>No_eval</em> mode. 
    For copyable types with efficient move, this may mean turning some moves into copies:</p>
		
<pre>
string f(const string s) <em>// `s` is const because the first declaration of `f()` has a postcondition</em>
{
  <em>// long function body that only reads `s`</em>
  return s;              <em>// copy, used to be a move</em> 
}
</pre>

<p> This is arguably inconvenient, however this remains within the normal rules of C++:
    if an object is declared <code>const</code> then in cannot be moved-from. It should be noted that, for the scope of MVP,
		the only viable alternative is to make postconditions that refer to non-reference function parameters invalid.
		For the post-MVP future the planned solution is for the user to request that copies of function arguments be done on the side,
		as described in section <a href="#con.syn.arg">{con.syn.arg}</a>.</p>
	
<p>The additional <code>const</code> qualifier still does not affect the type of the function:</p>

<pre>
int f(const int i) 
  POST(r: r != i);

int (*fp)(int) = &amp;f; <em>// ok</em>
</pre>



<h4><a class="sect" id="pro.arg.out">3.13.1 Can the problem be avoided by inspecting function arguments instead?<span class="link">{pro.arg.out}</span></a></h4>


<p> It has been suggested that the problem with function parameters referenced in postconditions could be avoided if we checked the values of function 
    arguments used to initialize the function parameters, instead of checking the parameters themselves:</p>
		
<pre>
int f(int i) POST(r: r != i);

int a = 1;
int b = f(a); <em>// in postcondition read value of `a` rather than value of `i`</em>
</pre>

<p> This idea will not work for more complex cases, unless a copy of the argument is made on the side. 
    First, you cannot assume that the value of the argument remains unchanged as the function is executed, due to aliasing problem.
		</p>

<pre>
int f(int a, int&amp; ref)
  POST(r: r != a)
{
  --ref;
  return a - 1;
}

int i = 1;
f(i, i);   <em>// at the end of f(), `i` has different value than `a`</em>
</pre>
	
<p> Another problem with the proposed idea is that we may not have the function argument of the same type as the function parameter:</p>

<pre>
string f(string s)
  POST(r: s.empty() || r == s);

auto x = "text"; <em>// type of `x` is `const char*`</em>
f(x);            <em>// cannot call `x.empty()`</em>
</pre> 	
	



<h3><a class="sect" id="pro.saf">3.14. Arbitrary expressions as predicates<span class="link">{pro.saf}</span></a></h3>



<p> <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2680r1.pdf"
       title="Gabriel Dos Reis, &ldquo;Contracts for C++: Prioritizing Safety&rdquo;">[P2680R1]</a> 
       explores the idea of statically preventing the usage of contract predicates with side effects
    visible outside of its cone of evaluation. However, as of today, it is not clear if thus limited preconditions
    are practically useful. This is discussed in 
    <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2570r2.html"
          title="Andrzej Krzemieński, &ldquo;Contract predicates that are not predicates&rdquo;">[P2570R2]</a>.
    SG21 decided not to pursue this direction for the Contracts MVP. As a result,
    any expression contextually convertible to <code>bool</code> can be used as a predicate
    in a contract annotations. These expressions can have side effects, and can trigger undefined behavior.
    This is because statically preventing them is too hard, and sometimes undesirable.    
    </p>

    
<p> Poll 3 (2022-12-14)</p>

<div class="poll">
<p> SG21 should attempt to design a model for safe programming in C++ as part of the contracts MVP, 
    despite the existence of SG23, and considering that this would be a diversion from the current
    SG21 roadmap (P2695R0).
    </p>

<table class="poll">
<tr><td>SF</td><td>F</td><td>N</td><td>A</td><td>SA</td></tr>
<tr><td>5</td><td>2</td><td>0</td><td>7</td><td>4</td></tr>
</table>

<p> Result: Not consensus </p>
</div>


<p> Poll 4 (2022-12-14)</p>

<div class="poll">
<p> Notwithstanding the previous poll, the contracts MVP should contain contracts-checking 
    predicates that are free of certain types of UB and free of side effects outside of their
    cone of evaluation, as proposed in D2680R1, and SG21 should spend further time reviewing 
    this design, considering that this would be a diversion from the current SG21 roadmap (P2695R0). 
    </p>

<table class="poll">
<tr><td>SF</td><td>F</td><td>N</td><td>A</td><td>SA</td></tr>
<tr><td>6</td><td>2</td><td>1</td><td>5</td><td>4</td></tr>
</table>

<p> Result: Not consensus </p>
</div>





<h3><a class="sect" id="pro.eff">3.15. Removal and duplication of side effects in predicates<span class="link">{pro.eff}</span></a></h3>


<p> Some implementation strategies may need to evaluate the same predicate in a precondition twice.
    For direct function calls, an implementation can easily insert the instrumentation code in the caller.
		This is desired as it gives better diagnostics. However, this is impossible when a function is called indirectly,
    either through a pointer or <code>std::function</code>: from the pointer signature we do not know if a function called
		has a precondition or not. To address that case, one thing an implementation could do is to compile the pre- and 
		post-condition checks into the function body. This would give the result that the pre-/post-conditions are checked normally
    when the function is called through an indirection, but are checked twice when the function is called directly: 
		once in the caller, and once inside the function body. We may want to enable such implementation strategies.		
		The consequence for the programmer is that when the predicate has side effects, these effects occur twice.</p>

<p> In a similar vein, in <em>Eval_and_abort</em> mode there are reasons not to evaluate the predicate when 
    the compiler can figure out what the result would be without evaluating it. This is for performance reasons.
    We want <em>Eval_and_abort</em> mode to be usable in production, so even though we want to guarantee
    that the program never executes the code after a failed declared contract annotation, we still want the
    program to perform fast. There is a number of ways how compiler may know the value of the predicate
    without evaluating it. One is when the same predicate is evaluated twice in a row:
    </p>
 
<pre>
bool p(int); <em>// defined in a different TU</em>

int produce() POST(r: p(r));
void consume(int i) PRE(p(i));

int main() {
  consume(produce()); <em>// can p() be called once?</em>
}
</pre>

<p> This seems redundant to call the same predicate twice. Of course, this seems so only if <code>p()</code> doesn't have side effects.
    If it does, and the program (or the programmer) relies on them, this elision can make the comprehension of the program harder,
	and the effects surprising.  <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2388r4.html"
     title="Andrzej Krzemieński, Gašper Ažman, &ldquo;Minimum Contract Support: either No_eval or Eval_and_abort&rdquo;">[P2388R4]</a> 
    additionally proposes the "partial elision" of side effects in a predicate. We received a feedback that the group is against it, 
    so this "partial elision" is not considered in this paper.
    </p>
 
<p> Because SG21 decided that contract predicates may have side effects, 
    the decision to evaluate a predicate zero, one two or more times has visible effects
    in the program. SG21 decided that calling the predicates zero, two or more times in 
    <em>Eval_and_abort</em> mode is allowed.
    </p>
    

<p> Poll 5 (Issaquah 2023)</p>
<div class="poll">
    <p> Do we want to require that a contract-checking predicate 
        is evaluated exactly once in eval_and_abort mode? 
        </p>

    <table class="poll">
    <tr><td>SF</td><td>F</td><td>N</td><td>A</td><td>SA</td></tr>
    <tr><td>2</td><td>2</td><td>0</td><td>9</td><td>15</td></tr>
    </table>

    <p> Result: Consensus against </p>
</div>

<p>Poll 6 (Issaquah 2023)</p>
<div class="poll">
<p> Do we want to allow that a contract-checking predicate is evaluated 
    zero or more times in eval_and_abort mode? 
    </p>

<table class="poll">
<tr><td>SF</td><td>F</td><td>N</td><td>A</td><td>SA</td></tr>
<tr><td>14</td><td>10</td><td>0</td><td>1</td><td>2</td></tr>
</table>

<p> Result: Consensus </p>
</div>

<p>Poll 7 (Issaquah 2023)</p>
<div class="poll">
<p> We want to adopt the rules on reordering the evaluation of 
    contract-checking predicates as described in P2751R0 proposal 3.4,
    contingent on a clarification that this reordering can be equivalently 
    formulated in terms of elision of evaluations inside repetitions of the
    given sequence of predicates.
    </p>

<table class="poll">
<tr><td>SF</td><td>F</td><td>N</td><td>A</td><td>SA</td></tr>
<tr><td>12</td><td>5</td><td>3</td><td>1</td><td>0</td></tr>
</table>

<p> Result: Consensus </p>
</div>


<h3><a class="sect" id="pro.ieo">3.16. Implementation-defined semantics of contract annotations<span class="link">{pro.ieo}</span></a></h3>

<p> Any time the control reaches a contract annotation it is implementation-defined which of the three things happens:
    </p>
    
<ol>
    <li><em>Ignore</em> semantic: No runtime effect (but entities in the contract predicates are ODR-used).</li>
    <li><em>Enforce</em> semantic: A predicate is evaluated according to contract predicate evaluation rules.
          If failure is determined then a contract violation handler is invoked, and if it returns normally the program is aborted.</li>
    <li><em>Observe</em> semantic: A predicate is evaluated according to contract predicate evaluation rules.
          If failure is determined then a contract violation handler is invoked, and if it returns normally the control resumes just after the contract annotation.</li>
    </ol>

<p> Two evaluations of the very same contract annotations at different times may have different semantics. 
    Compilers are allowed, but not required, to assign the same semantic to all contract annotations. This allows
    static selection of a semantic, as well as a dynamic selection of a semantic, as well linking libraries
    with different semantics baked in each of them. The use cases for this flexibility deemed important
    for the MVP, such as efficient distribution of packaged software, are described in 
    <a href="https://isocpp.org/files/papers/P2877R0.pdf"
       title="Joshua Berne, Tom Honermann, &ldquo;Contract Build Modes, Semantics, and Implementation Strategies&rdquo;"
       >[P2877R0]</a>
    </p>
    
<p> As a result, it is possible that the evaluation of a function like:</p>

<pre>
inline int fun(int i)
{
  ASSERT(pred(i));
  return i;
}
</pre>  

<p> does different things at different times, with possibly different side effects. Today such code qualifies as ODR-violation,
    but because we allow the provision that different evaluations of the same contract annotation can have different semantic,
    this fits into what is considered a correct program.</p>  
    
<p>Poll 11 (Varna 2023)</p>
<div class="poll">
<p> Modify the Contracts MVP as proposed by 
    <a href="https://isocpp.org/files/papers/P2877R0.pdf"
       title="Joshua Berne, Tom Honermann, &ldquo;Contract Build Modes, Semantics, and Implementation Strategies&rdquo;"
       >P2877R0</a>
    as presented.
    </p>

<table class="poll">
<tr><td>SF</td><td>F</td><td>N</td><td>A</td><td>SA</td></tr>
<tr><td>10</td><td>11</td><td>4</td><td>3</td><td>1</td></tr>
</table>

<p> Result: Consensus </p>
</div>


<p>Poll 12 (Varna 2023)</p>
<div class="poll">
<p> Modify the Contracts MVP as proposed by 
    <a href="https://isocpp.org/files/papers/P2877R0.pdf"
       title="Joshua Berne, Tom Honermann, &ldquo;Contract Build Modes, Semantics, and Implementation Strategies&rdquo;"
       >P2877R0</a>
    with Proposal 5 (Default Semantic) removed.
    </p>

<table class="poll">
<tr><td>SF</td><td>F</td><td>N</td><td>A</td><td>SA</td></tr>
<tr><td>6</td><td>10</td><td>7</td><td>2</td><td>3</td></tr>
</table>

<p> Weaker consensus than the previous poll. </p>
</div>


<h3><a class="sect" id="pro.hnd">3.17. User-controlled contract violation handler<span class="link">{pro.hnd}</span></a></h3>

<p> It is implementation-defined whether a program can replace the global violation handler. 
    A violation handler is a function returning <code>void</code> and taking an argument of type
    <code>const std::contracts::contract_violation &amp;</code>. The handler is replaced in a 
    similar way as you replace global <code>operator new</code>: by providing a definition 
    of the function <code>::handle_contract_violation</code>.
    </p> 

<p>Poll 13 (2023-04-20)</p>
<div class="poll">
<p> The Contracts MVP should have a standard interface for a link-time replaceable violation handler. </p>

<table class="poll">
<tr><td>SF</td><td>F</td><td>N</td><td>A</td><td>SA</td></tr>
<tr><td>10</td><td>5</td><td>1</td><td>0</td><td>1</td></tr>
</table>

<p> Result: Consensus </p>
</div> 


<p>Poll 20 (Varna 2023)</p>
<div class="poll">
<p> The <code>&lt;contract&gt;</code> header proposed in P2811R5  should be renamed 
    to <code>&lt;contracts&gt;</code> to be consistent with the proposed namespace contracts.
    </p>

<table class="poll">
<tr><td>SF</td><td>F</td><td>N</td><td>A</td><td>SA</td></tr>
<tr><td>10</td><td>8</td><td>2</td><td>1</td><td>0</td></tr>
</table>

<p> Result: Consensus</p>
</div> 


<p>Poll 21 (Varna 2023)</p>
<div class="poll">
<p> Amend the Contracts MVP as proposed by D2811R6 (P2811R5) with the
    header name changed as per the above poll.
    </p>

<table class="poll">
<tr><td>SF</td><td>F</td><td>N</td><td>A</td><td>SA</td></tr>
<tr><td>13</td><td>5</td><td>4</td><td>0</td><td>0</td></tr>
</table>

<p> Result: Consensus</p>
</div> 
 
 
 
 
<h3><a class="sect" id="pro.tfp">3.18. A throw from a predicate <span class="link">{pro.tfp}</span></a></h3>



<p> As proposed in <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2751r0.pdf"
    title="Joshua Berne, &ldquo;Evaluation of Checked Contract-Checking Annotations&rdquo;">[P2751R0]</a>
    and
    <a href="https://isocpp.org/files/papers/P2811R5.pdf"
       title="Joshua Berne, &ldquo;Contract-Violation Handlers&rdquo;"
       >[P2811R5]</a>,
    A throw from the evaluation of the contract predicate results in throwing an exception,
    this is considered a violation of the corresponding contract annotation: contract violation handler
    is invoked and potentially the program is aborted. This is as if a contract predicate was 
    evaluated inside a <code>try</code>-<code>catch</code> statement, and the contract violation handler invoked from
    the <code>catch</code>-clause. The contract violation handler can decide whether to rethrow the exception or to
    swallow it.
    </p>
    
    
    
<p>Poll 8 (Issaquah 2023)</p>
<div class="poll">
<p> Poll: In case the evaluation of a contract-checking predicate throws an exception,
    we want std::terminate to be called.
    </p>

<table class="poll">
<tr><td>SF</td><td>F</td><td>N</td><td>A</td><td>SA</td></tr>
<tr><td>0</td><td>2</td><td>5</td><td>14</td><td>8</td></tr>
</table>

<p> Result: Consensus against.</p>
</div>


<p>Poll 9 (Issaquah 2023)</p>
<div class="poll">
<p> In case the evaluation of a contract-checking predicate throws an exception, we want this to be treated as a contract violation. 
    </p>

<table class="poll">
<tr><td>SF</td><td>F</td><td>N</td><td>A</td><td>SA</td></tr>
<tr><td>7</td><td>7</td><td>3</td><td>3</td><td>7</td></tr>
</table>

<p> No consensus </p>
</div>


<p>Poll 10 (Issaquah 2023)</p>
<div class="poll">
<p> In case the evaluation of a contract-checking predicate throws an exception, we want to propagate that exception out of the contract check.  
    </p>

<table class="poll">
<tr><td>SF</td><td>F</td><td>N</td><td>A</td><td>SA</td></tr>
<tr><td>5</td><td>5</td><td>4</td><td>3</td><td>10</td></tr>
</table>

<p> No consensus </p>
</div>


  
<p>Poll 16 (2023-05-18)</p>
<div class="poll">
<p> Whether a contract-checking annotation is evaluated should never 
    change the result of the noexcept operator or the type of a function
    pointer to which the contract annotation is attached, provided that
    in both cases the code is well-formed.
    </p>

<table class="poll">
<tr><td>SF</td><td>F</td><td>N</td><td>A</td><td>SA</td></tr>
<tr><td>13</td><td>5</td><td>1</td><td>0</td><td>0</td></tr>
</table>

<p> Consensus</p>
</div>


<p>Poll 17 (2023-05-18)</p>
<div class="poll">
<p> Throwing an exception from the evaluation of a contract-checking
    predicate shall be treated as a contract violation, and invoke 
    the violation handler, regardless whether the function is declared
    `noexcept`, as proposed in P2811.
    </p>

<table class="poll">
<tr><td>SF</td><td>F</td><td>N</td><td>A</td><td>SA</td></tr>
<tr><td>8</td><td>7</td><td>2</td><td>0</td><td>1</td></tr>
</table>

<p> Consensus</p>
</div>
  
  
<p>Poll 18 (2023-05-18)</p>
<div class="poll">
<p> Throwing an exception from a contract violation handler
    shall invoke the usual exception semantics: stack unwinding occurs,
    and if a `noexcept` barrier is encountered during unwinding, 
    std::terminate is called, as proposed in P2811.
    </p>

<table class="poll">
<tr><td>SF</td><td>F</td><td>N</td><td>A</td><td>SA</td></tr>
<tr><td>10</td><td>7</td><td>2</td><td>0</td><td>0</td></tr>
</table>

<p> Consensus</p>
</div>


<p>Poll 19 (2023-05-18)</p>
<div class="poll">
<p> Preconditions, postconditions, and assertions shall all
    behave the same way with respect to throwing an exception
    from the predicate or the violation handler.
    </p>

<table class="poll">
<tr><td>SF</td><td>F</td><td>N</td><td>A</td><td>SA</td></tr>
<tr><td>10</td><td>8</td><td>0</td><td>0</td><td>0</td></tr>
</table>

<p> Consensus</p>
</div>


 
 
 
<h3><a class="sect" id="pro.mbp">3.19. Misbehaving predicates<span class="link">{pro.mbp}</span></a></h3>
 

<p>Poll 14 (Issaquah 2023)</p>
<div class="poll">
<p> When the evaluation of a contract-checking predicate exits the control flow other
    than by returning or throwing (for example, abort or longjmp), the behavior is 
    as if it were not in a contract-checking predicate. 
    </p>

<table class="poll">
<tr><td>SF</td><td>F</td><td>N</td><td>A</td><td>SA</td></tr>
<tr><td>19</td><td>11</td><td>0</td><td>1</td><td>0</td></tr>
</table>

<p> Result: Consensus </p>
</div> 


<p>Poll 15 (Issaquah 2023)</p>
<div class="poll">
<p> We would like to non-normatively state the recommended practice that
    implementations should consider treating undefined behavior in the
    evaluation of a contract predicate as a contract violation. 
    </p>

<table class="poll">
<tr><td>SF</td><td>F</td><td>N</td><td>A</td><td>SA</td></tr>
<tr><td>5</td><td>11</td><td>5</td><td>2</td><td>8</td></tr>
</table>

<p> Result: Not consensus </p>
</div> 



<h2><a class="sect" id="con">4. Controversial aspects <span class="link">{con}</span></a></h2>	


<p>This section lists points of controversy inside SG21 for the recent contract design. For each of these points, we
   require a poll to be taken, to determine the group direction.</p>



<h3><a class="sect" id="con.syn">4.1. The choice of syntax<span class="link">{con.syn}</span></a></h3>


<p> There are two visions for the syntax to describe contract annotations with significant support in SG21.</p>

<p>One is to use notation similar to attributes (but not 100% compatible with attributes):</p>

<pre>int select(int i, int j)
  [[pre: i &gt;= 0]]
  [[pre: j &gt;= 0]]
  [[post r: r &gt;= 0]]      <em>// r names the return value</em>
{
  [[assert: _state &gt;= 0]];

  if (_state == 0) return i;
  else             return j;
}
</pre>

<p>The other is to use notation similar to lambdas (but not 100% compatible with lambdas):</p>

<pre>int select(int i, int j)
  pre{ i &gt;= 0 }
  pre{ j &gt;= 0 }
  post(r){ r &gt;= 0 }      <em>// r names the return value</em>
{
  assert{ _state &gt;= 0 };

  if (_state == 0) return i;
  else             return j;
}
</pre>

<p> The rationale for using the later syntax has been provided in <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2461r1.pdf">[P2461R1]</a>.
    The analysis of pros and cons of using the former syntax has been provided in
    <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2487r1.html" 
	   title="Andrzej Krzemieński, &ldquo;Is attribute-like syntax adequate for contract annotations?&rdquo;">[P2487R1]</a>.
		</p>

<p> The primary argument in favor of quasi-attribute notation is to stress semantic characteristics similar to attributes. 
    The common understanding of attributes is that they are hints for generating warnings or performing optimizations. Their removal
		should not affect the correctness of the program (even though it is easy to construct an example using <code>no_unique_address</code>
		that contradicts this claim).</p>
		
<p> Contract annotations &mdash; at least one model thereof &mdash; shares similar features: they are hints for tools for generating warnings
    or emitting an instrumentation code. If these annotations are removed <em>from a correct program</em> (one that does not violate the declared
		contract annotations), this does not affect the correctness of the program.
    </p> 
		
<p> The primary arguments in favor of quasi-lambda syntax is to avoid the problems reported for quasi-attribute syntax 
    (e.g., that they look like attributes but do not follow other characteristics of attributes) and to offer an intuitive
		syntax for one of the future extensions: making copies of function arguments for use in postconditions.





<h3><a class="sect" id="con.trv">4.2 Annotations on trivial ops <span class="link">{con.trv}</span></a></h3>
  
<p> When a trivial function, such as a trivial destructor, contains a contract annotation, does it affect
    its triviality? Clearly, the evaluation of a contract predicate is a non-trivial operation. 
    The options here are:</p>
    
<ol>
<li>An operation is never trivial when it contains a contract annotation.</li>
<li>Contract annotation on a trivial operation is never tested.</li>
</ol>
  
<p> <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2834r0.pdf"
       title="Joshua Berne, John Lakos, &ldquo;Semantic Stability Across Contract-Checking Build Modes&rdquo;"
       >[P2834R0]</a>
    discusses this in detail and recommends option 2.</p>



<h3><a class="sect" id="con.lbd">4.3. Implicit lambda captures from contract predicates <span class="link">{con.lbd}</span></a></h3>          


<p><a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2834r0.pdf"
       title="Joshua Berne, John Lakos, &ldquo;Semantic Stability Across Contract-Checking Build Modes&rdquo;"
       >[P2834R0]</a> also discusses how some interpretations of "ignore" semantics can unexpectedly change
       the behavior of a program when a contract predicate on a labmda with a default by-value capture odr-uses
       an entity from the enclosing scope. The example from the paper:</p>

<pre>
std::function&lt;int()&gt; f(std::shared_ptr&lt;S&gt; sp)
{
  int *x = &amp;sp-&gt;d_x; <em>// Raw pointer </em>x<em> is invalidated when </em>*sp<em> is destroyed.</em>
  
  return [=]()       <em>// lambda having by-value capture default</em>
  PRE(sp != nullptr) <em>// precondition that odr-uses </em>sp<em></em>
  {
    return *x;       <em>// lambda body that does not odr-use </em>sp<em></em>
  };
}
</pre>


<p> In this example, the only code that odr-uses <code>sp</code> is the contract predicate. If semantic <em>ignore</em>
    means also "do not odr-use entities", switching between semantics means capturing or not an entity , and this implies
    extending or not the lifetime of <code>*sp</code>
    which has an effect on the correctness of the program. The paper lists two ways to prevent changing the meaning of the 
    program in different cntract semantics:</p>
    
<ol>
<li>Odr-used entities trigger implicit lambda captures even in <em>ignore</em> semantics.</li>
<li>Implicit lambda captures from contract predicates make the program ill-formed.</li>
</ol>

<p> While the second option seems to impose arbitrary constraints on programs, it maintains the guarantee that 
    semantic <em>ignore</em> never adds a runtime-cost (such as the size of the closure objects). </p>


<h3><a class="sect" id="con.cor">4.4. Annotations on coroutines <span class="link">{con.cor}</span></a></h3>


<p> Coroutines require dedicated attention, as, unlike in ordinary functions, the point of returning to the caller
    is not the same as the point of ending the coroutine. So the common notion of a postcondition &mdash; 
	that it is something that the function guarantees to the caller (1) at the end (2) &mdash; no longer applies.
	"Guarantees to the caller" and "at he end" are now different things. This is discussed in detail in
	<a href="https://isocpp.org/files/papers/P2957R0.html"
           title="Andrzej Krzemieński, Iain Sandoe, &ldquo;Contracts and coroutines&rdquo;">[P2834R0]</a>.</p>


<h3><a class="sect" id="con.int">4.5. The interleaving of pre- and post-conditions <span class="link">{con.int}</span></a></h3>
		  
<p>Can a precondition annotation follow a postcondition annotation?</p>

<pre>
pair&lt;T, U&gt; f(pair&lt;T, U&gt; input)
  PRE(input.first &gt;= 0)
  POST(output: output.first &gt; 0)
  PRE(input.second &gt;= 0)
  POST(output: output.second &gt; 0);
</pre>


<p> SG21 has now a dedicated paper for tracking the outstanding issues: 
    <a href="https://isocpp.org/files/papers/P2896R0.pdf"
           title="Timur Doumler, &ldquo;Outstanding design questions for the Contracts MVP&rdquo;">[P2896R0]</a>.</p>


<h2><a class="sect" id="ack">5. Acknowledgments
    <span class="link">{ack}</span></a></h2>
		
<p> This paper is a summary of SG21 discussions; all SG21 members contributed to this paper. 
    John McFarlane suggested the idea to make implicit copies of trivially-copyable types. 
		Walter E. Brown pointed out that putting pre-/post-condition checks inside function bodies is not a necessity, 
    and that alternate implementations &mdash; such as a thunk &mdash; exist.</p>


<h2><a class="sect" id="ref">6. References
    <span class="link">{ref}</span></a></h2>

<ul>

  <li>[P0542R5] — G. Dos Reis, J. D. Garcia, J. Lakos, A. Meredith, N. Myers, B. Stroustrup,
      "Support for contract based programming in C++" <br>
      (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0542r5.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0542r5.html</a>).
      </li>
      <!--
        <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p0542r5.html"
           title="G. Dos Reis, J. D. Garcia, J. Lakos, A. Meredith, N. Myers, B. Stroustrup, &ldquo;Support for contract based programming in C++&rdquo;"
           >[P0542R5]</a>
        -->
			
	<li>[P1289R1] — J. Daniel Garcia, Ville Voutilainen, "Access control in contract conditions" <br>
		(<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1289r1.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1289r1.pdf</a>).
		</li>
			
  <li>[P1323R2] — Hubert S.K. Tong, "Contract postconditions and return type deduction" <br>
      (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1323r2.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1323r2.html</a>).
      </li>
	
  <li>[P2388R4] — Andrzej Krzemieński, Gašper Ažman, "Minimum Contract Support: either No_eval or Eval_and_abort" <br>
      (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2388r4.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2388r4.html</a>).
      </li>
      <!--
        <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2388r4.html"
           title="Andrzej Krzemieński, Gašper Ažman, &ldquo;Minimum Contract Support: either No_eval or Eval_and_abort&rdquo;">[P2388R4]</a>
        -->
	
  <li>[P2461R1] — Gašper Ažman, Caleb Sunstrum, Bronek Kozicki, "Closure-Based Syntax for Contracts" <br>
      (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2461r1.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2461r1.pdf</a>).
      </li>	
			
  <li>[P2466R0] — Andrzej Krzemieński, "The notes on contract annotations" <br>
      (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2466r0.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2466r0.html</a>).
      </li>	

  <li>[P2487R1] — Andrzej Krzemieński, "Is attribute-like syntax adequate for contract annotations?" <br>
      (<a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2487r1.html">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2487r1.html</a>).
      </li>		
	
  <li>[P2521R1] — Gašper Ažman, Joshua Berne, Bronek Kozicki, Andrzej Krzemieński, Ryan McDougall, Caleb Sunstrum, "Contract support — Working Paper" (the previous revision of this paper)<br>
      (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2521r1.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2521r1.html</a>).
      </li>	
	
  <li>[P2680R1] — Gabriel Dos Reis, "Contracts for C++: Prioritizing Safety" <br>
      (<a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2680r1.pdf">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2680r1.pdf</a>).
      </li>	
      <!--
        <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2680r1.pdf"
           title="Gabriel Dos Reis, &ldquo;Contracts for C++: Prioritizing Safety&rdquo;">[P2680R1]</a>
        -->
      
  <li>[P2570R2] — Andrzej Krzemieński, "Contract predicates that are not predicates" <br>
      (<a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2570r2.html">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2570r2.html</a>).
      </li>	
      
  <li>[P2751R0] — Joshua Berne, "Evaluation of Checked Contract-Checking Annotations" <br>
      (<a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2751r0.pdf">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2751r0.pdf</a>).
      </li>	
      
  <li>[P2811R5] — Joshua Berne, "Contract-Violation Handlers" <br>
      (<a href="https://isocpp.org/files/papers/P2811R5.pdf">https://isocpp.org/files/papers/P2811R5.pdf</a>).
      </li>	
      <!--
        <a href="https://isocpp.org/files/papers/P2811R5.pdf"
           title="Joshua Berne, &ldquo;Contract-Violation Handlers&rdquo;">[P2811R5]</a>
        -->     
 
  <li>[P2877R0] — Joshua Berne, Tom Honermann, "Contract Build Modes, Semantics, and Implementation Strategies" <br>
      (<a href="https://isocpp.org/files/papers/P2877R0.pdf">https://isocpp.org/files/papers/P2877R0.pdf</a>).
      </li>	
      <!--
        <a href="https://isocpp.org/files/papers/P2877R0.pdf"
           title="Joshua Berne, Tom Honermann, &ldquo;Contract Build Modes, Semantics, and Implementation Strategies&rdquo;">[P2877R0]</a>
        -->
        
   <li>[P2834R0] — Joshua Berne, John Lakos, "Semantic Stability Across Contract-Checking Build Modes" <br>
      (<a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2834r0.pdf ">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2834r0.pdf</a>).
      </li>	
      <!--
        <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2834r0.pdf"
           title="Joshua Berne, John Lakos, &ldquo;Semantic Stability Across Contract-Checking Build Modes&rdquo;">[P2834R0]</a>
        -->
		
	<li>[P2885R1] — Timur Doumler, Gašper Ažman, Joshua Berne, Andrzej Krzemieński, Ville Voutilainen, "Requirements for a Contracts syntax" <br>
      (<a href="https://isocpp.org/files/papers/P2885R1.pdf">https://isocpp.org/files/papers/P2885R1.pdf</a>).
      </li>	
      <!--
        <a href="https://isocpp.org/files/papers/P2885R1.pdf"
           title="Timur Doumler, Gašper Ažman, Joshua Berne, Andrzej Krzemieński, Ville Voutilainen, &ldquo;Requirements for a Contracts syntax&rdquo;">[P2885R1]</a>
        -->
 
    <li>[P2896R0] — Timur Doumler, "Outstanding design questions for the Contracts MVP" <br>
      (<a href="https://isocpp.org/files/papers/P2896R0.pdf">https://isocpp.org/files/papers/P2896R0.pdf</a>).
      </li>	
      <!--
        <a href="https://isocpp.org/files/papers/P2896R0.pdf"
           title="Timur Doumler, &ldquo;Outstanding design questions for the Contracts MVP&rdquo;">[P2896R0]</a>
        -->
 
 
 	<li>[P2957R0] — Andrzej Krzemieński, Iain Sandoe, "Contracts and coroutines" <br>
      (<a href="https://isocpp.org/files/papers/P2957R0.html">https://isocpp.org/files/papers/P2957R0.html</a>).
      </li>	
      <!--
        <a href="https://isocpp.org/files/papers/P2957R0.html"
           title="Andrzej Krzemieński, Iain Sandoe, &ldquo;Contracts and coroutines&rdquo;">[P2834R0]</a>
        -->

</ul>


</body></html>
