﻿<!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; }

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>Is attribute-like syntax adequate for contract annotations?</title>

</head>
<body>

<table class="header"><tbody>
  <tr>
    <th>Document number:&nbsp;&nbsp;</th><th> </th><td>P2487R1</td>
  </tr>
  <tr>
    <th>Date:&nbsp;&nbsp;</th><th> </th><td>2023-06-11</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>
      </td>
  </tr>
</tbody></table>



<h1 id="attribute-like-syntax-for-contract-annotations">Is attribute-like syntax adequate for contract annotations?</h1>


<p> This paper is an attempt to structure the discussion on the choice of syntax for contract annotations.</p>

<p> <a href="https://wg21.link/p0542"
       title="Dos Reis, Garcia, Lakos, Meredith, Myers, Stroustrup, &quot;Support for contract based programming in C++&quot;">[P0542]</a>
    and 
	<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> 
     propose a syntax that appears similar to attributes:
	 </p>

<pre><code class="lang-c++">int f(int i)
  <span class="hljs-string">[[pre: i &gt;= 0]]</span>
  <span class="hljs-string">[[post r: r &gt;= 0]]</span>;
</code></pre>

<p><a href="https://isocpp.org/files/papers/P2461R0.pdf" title="Ažman, Sunstrum, Kozicki, &quot;Closure-Based Syntax for Contracts&quot;">[P2461]</a> proposes, similarly to <a href="https://wg21.link/n1962" title="Crowl, Ottosen, &quot;Proposal to add Contract Programming to C++&quot;">[N1962]</a>, an
alternate syntax, nothing like attributes:</p>

<pre><code class="lang-c++"><span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">f</span><span class="hljs-params">(<span class="hljs-keyword">int</span> i)</span>
  pre</span>{i &gt;= <span class="hljs-number">0</span>}
  post(r){r &gt;= <span class="hljs-number">0</span>};
</code></pre>

<p>And we could invent more syntax alternatives, for instance:</p>

<pre>int f(int i)
  pre(i &gt;= 0)
  post(r: r &gt;= 0);
</pre>

<p> Rather than comparing different syntax choices, we try to answer the question:
    is attribute-like syntax suitable for contract annotations.
	It is clear that contract annotations using attribute-like syntax proposed in 
    <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>
    are not attributes according to the grammar productions of C++. Instead,
    the question we try to answer is: do we want the programmers to <em>think</em> 
    of them as attributes.
    </p>



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


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


<ol>
  <li>Updated the discussion on ignorability, based on <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2552r2.pdf"
   title="Timur Doumler, &ldquo;On the ignorability of standard attributes&rdquo;">[P2552R2]</a>
	  and the revised C++ Standard (<a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4944.pdf" 
          title="Thomas Köppe, &ldquo;Working Draft, Standard for Programming Language C++&rdquo;">[N4944]</a>).</li>
  <li>Added discussion of expressions in attributes.</li>
  <li>Added discussion on semantic ignorability criterion, presented in <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2552r2.pdf"
   title="Timur Doumler, &ldquo;On the ignorability of standard attributes&rdquo;">[P2552R2]</a>.</li>
</ol>



<h2><a id="ign" class="sect">"Ignorable" <span class="link">{ign}</span></a></h2>


<p> Interestingly, one argument brought up in favor of the attribute-like syntax is that
    contract annotations are "ignorable", whereas one argument against the attribute-like
	syntax say that contract annotations are not "ignorable". This indicates that we do
	not have a shared understanding of what "ignorable" means.</p>
	
<p> We can get the best approximation of the term from the C and C++ standards. The C Standard
    (<a href="http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2596.pdf">[N2596]</a>)
	has the following.</p>

<p>6.7.11 p2:</p>
<blockquote>
<p>Support for any of the standard attributes specified in this document is implementation-defined
and optional. For an attribute token (including an attribute prefixed token) not specified in this
document, the behavior is implementation-defined. Any attribute token that is not supported by the
implementation is ignored.</p>
</blockquote>

<p>4 p5:</p>

<blockquote>
<p>A strictly conforming program shall use only those features of the language and library specified
in this document. It shall not produce output dependent on any unspecified, undefined, or
implementation-defined behavior, and shall not exceed any minimum implementation limit.</p>
</blockquote>

<p>6.7.11.1 p3:</p>

<blockquote>
<p> [...] A strictly conforming program using a standard attribute remains strictly conforming in the absence of that
attribute. <sup>166)</sup></p>
</blockquote>

<p>Footnote 166:</p>

<blockquote>
<p>Standard attributes specified by this document can be parsed but ignored by an implementation without changing the
semantics of a correct program; the same is not true for attributes not specified by this document</p>
</blockquote>

<p>The C++ Standard <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4944.pdf" 
          title="Thomas Köppe, &ldquo;Working Draft, Standard for Programming Language C++&rdquo;">[N4944]</a> has the following to say:</p>
<p>9.12.1 p1:</p>

<blockquote>
<p>Attributes specify additional information for various source constructs such as types, variables, names, blocks,
or translation units.</p>
</blockquote>

<p>9.12.1 p6:</p>

<blockquote>
<p>For an <em>attribute-token</em> [...] not specified in this document, the behavior is
implementation-defined; any such <em>attribute-token</em> that is not recognized by the implementation is ignored.</p>

<p> [<em>Note 4</em>: A program is ill-formed if it contains an <code>attribute</code> specified in 9.12 that violates the rules specifying to which
entity or statement the attribute can apply or the syntax rules for the attribute’s <code>attribute-argument-clause</code>, if any.
<em>— end note</em>]</p>
</blockquote>


<p> The definition in C does not make it quite clear if "ignore" means "must parse correctly, but has no semantics",
or "does not even have to parse correctly". For instance, is an implementation allowed to accept the following code without 
emitting any diagnostic?</p>

<pre>void f(auto [[noreturn(int)]] i);
</pre>

<p> The C++ definition, on the other hand, makes it clear that "ignore" means "must parse correctly, 
    but has no semantics".
    </p>

<p> Let's introduce two definitions to tell apart these two interpretations of "ignorability":</p>
    
<dl>
    <dt>Syntactic ignorability</dt>
    <dd>This is the WG14 model. An implementation, while doing the parsing of the source code can ignore any balanced 
        sequence of tokens between <code>[[</code> and <code>]]</code>.</dd>

    <dt>Semantic ignorability</dt>
    <dd>An implementation is required for every standard attribute to verify at compile-time if all the constraints corresponding 
        to the attribute are satisfied, such as what it appertains to, how many times it occurs in the attribute-list,
        does it have the correct number and types of parameters. It is also required to ODR-use entities in the expression 
        if it is part of attribute's argument list.
        Other than that an implementation can translate 
        the program as if the attribute was absent. This is discussed in more detail in <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2552r2.pdf"
   title="Timur Doumler, &ldquo;On the ignorability of standard attributes&rdquo;">[P2552R2]</a>.
</dd>
   </dl>

<p> While the syntactic ignorability may disincetivize the implementations from detecting bugs in the attribute usage,
    it also provides a better backwards compatibility. For instance, the following code is correct in C++17:</p>

<pre>[[nodiscard("get ownership")]] int * allocate();
</pre>

<p> However, if we compiled it with C++14 we would get a compiler error when syntactic conformance of attributes is verified.
    This is because in C++14 attribute <code>nodiscard</code> was recognized but was allowed no argument clause.</p>


<p> The semantic ignorability corresponds to the semantics of contract annotations in translation 
	mode <em>No_Eval</em>, as described in <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>:
	the syntactic and type-system correctness are verified, the entities in the predicate are ODR-used, but
    other than that nothing happens.</p>	



<h2><a id="exp" class="sect">Parsing expressions <span class="link">{exp}</span></a></h2>
 

<p> It was reported in the past that having to parse C++ expressions inside attributes 
    is challenging because attributes were meant to be simple annotations to be parsed 
	at earlier stages of translation, where no type system information is present yet.
	</p>

<p> The requirement to parse C++ expressions inside <code>[[_]]</code> is implementable.
    The implementation would have to recognize the sequence <code>[[pre: _]]</code> as
	special, and treat it distinctively, as a keyword. However, the requirement to parse expressions
	breaks the simple model for attributes: they can no longer be parsed at earlier phases
	of translation: their well-formedness now depends on the type system.
	</p> 
	
<p> In response to this, we could say that C++ are not attributes, but a different feature
    that also happens to use the <code>[[_]]</code> notation. More, since C++23 the language
	has now attribute <code>[[assume(_)]]</code> which already requires parsing C++ expressions. 
	See <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1774r8.pdf" 
    title="Timur Doumler, &ldquo;Portable assumptions&rdquo;">[P1774R8]</a>.
	</p> 
	


<h2><a id="dvi" class="sect">"Declarative" vs "imperative" <span class="link">{dvi}</span></a></h2>


<p> There are (at least) two possible models for describing semantics contract annotations. The first is that
    they are predicates (in the mathematical sense) for describing what constitutes an incorrect program
    at a given point in program execution. We can call it a "declarative" model. The other model is that
    contract annotations give a programmer a tool to execute arbitrary code at certain points in program
    execution, which can include control flows, such as <code>throw</code>-expression. We can call it an
    "imperative" model. An example of such model is proposed in <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1893r0.pdf" title="Tomazos, &quot;Proposal of Contract Primitives&quot;">[P1893]</a>, and it takes contract support
    close to <code>call</code> and <code>return</code> features described in 
    <a href="https://www.stroustrup.com/wrapper.pdf" title="Stroustrup, &quot;Wrapping C++ Member Function Calls&quot;">[STROUSTRUP]</a>
    and
    <a href="https://www.stroustrup.com/dne.html" title="Stroustrup, &quot;The Design and Evolution of C++&quot;">[DnE]</a>
    .
    </p> 
    

    
<p> The preference of either of the models also affects the choice of the syntax for contract annotations.
    In the declarative model, the attribute-like syntax is a well suited candidate. But it is counterintuitive
    if we adopt the imperative model.</p>    



<h2><a id="reo" class="sect">"Reorderable" <span class="link">{reo}</span></a></h2>	
    
    
<p> Although it is not specified anywhere formally, the intuitive expectation of the attributes
    is that while you can reorder two attributes inside a single <em>attribute-specifier</em>
    without changing the meaning, you cannot safely reorder two <em>attribute-specifier</em>s:

</p><pre>[[a, b]] int f(); <em>// same as [[b, a]] int f();</em>

[[c]] [[d]] int g(); <em>// different than [[d]] [[c]] int g();</em>
</pre> 

<p> This is compatible with contract annotations. One cannot reorder the following two contract annotations,
    as the short-circuiting property would be compromised:</p>

<pre>int f(int * p) 
  [[pre: p != nullptr]]
  [[pre: *p &gt; 0]];
</pre> 

    

<h2><a id="ord" class="sect">Ordering <span class="link">{ord}</span></a></h2>	


<p> Today, it is difficult to remember in which order declarators like <code>noexcept</code>, 
    <code>const</code> <code>-&gt;</code> and attributes should appear in function 
    declarations after the parentheses:</p>

<pre>int f(int) const noexcept [[gnu::fastcall]]; <em>// correct or ill-formed?</em>
</pre>

<p> Adding a new declarator to the list, looking similar to attributes, will introduce a new:
    sort of dilemma: how these contact annotations should be ordered relative to attributes
    appertaining to function type:</p>
 
<pre>int f1(int i)               <em>// correct declaration?</em>
  [[pre: i &gt; 0]]
  [[using gnu: fastcall]]
  [[post r: r &gt; 0]]; 
  
int f2(int i)               <em>// correct declaration?</em>
  [[using gnu: fastcall]]
  [[pre: i &gt; 0]]
  [[post r: r &gt; 0]]; 
  
int f3(int i)               <em>// correct declaration?</em>
  [[pre: i &gt; 0]]
  [[post r: r &gt; 0]]
  [[using gnu: fastcall]]; 
</pre> 



<h2><a id="cnt" class="sect"><code>[[_]]</code> as container <span class="link">{cnt}</span></a></h2>	


<p> The present intuition that people might adopt is that two pairs of square brackets
    (an <em>attribute-specifier</em>) is a "container" that can hold zero, one or more 
    comma-separated attributes:</p>
    
<pre>[[]] int f(); <em>// ok: zero attributes</em>
[[noreturn]] int g(); <em>// ok: one attribute</em>
[[noreturn, nodiscard]] int h(); <em>// ok: two attributes</em>
</pre>
    
<p> Contract annotations would not fit into this intuition. </p>    
    
	
	
<h2><a id="tea" class="sect">Type and Effect analysis <span class="link">{tea}</span></a></h2>	


<p>Imagine a system of annotations -- <code>[[writable]]</code>, <code>[[readable]]</code> -- that helps track the lifetime of
a heap-allocated objects:</p>
<pre><code class="lang-c++">int* <span class="hljs-string">[[writable]]</span> allocate ();
int* <span class="hljs-string">[[readable]]</span> fill(int* <span class="hljs-string">[[writable]]</span> p);
void read(int* <span class="hljs-string">[[readable]]</span> p);
void deallocate(int* <span class="hljs-string">[[writable]]</span> p);
</code></pre>

<p>Thus, function <code>deallocate()</code> requires the pointer to be <code>writable</code>. <code>readable</code> implies <code>writable</code>. Function <code>allocate()</code> produces a <code>writable</code> value. Function <code>fill()</code> upgrades the <code>writable</code> property to <code>readable</code>. This constitutes an <em>annotated type system</em> that can be subject to <em>Type an Effect analysis</em>. A tool can try to determine if 

<code>deallocate()</code> or <code>fill()</code> is ever called with a pointer that is not <code>writable</code>, or if <code>read()</code> is ever called with a pointer that is not <code>readable</code>. </p>

<p>We could invent a different system of annotations for tracking the ownership of a resource:</p>

<pre><code class="lang-c++">Res* <span class="hljs-string">[[in_session]]</span> acquire ();
void use(Res* <span class="hljs-string">[[in_session]]</span> r);
void release(Res* <span class="hljs-string">[[in_session, ends_session]]</span> p);
</code></pre>

<p> This constitutes another Effect system, and a similar analysis could 
    be performed using this system. And we could invent more and more such 
    systems. The attributes are used to extend the type system with the 
    effects system. The effects system is not enforced by the compiler, but 
    is formal enough to enable a certain kind of analysis. The attribute
	syntax is a natural choice for expressing these effects.
	</p>
 
<p>Now, one of the use cases for contract support framework is to provide an automated way for describing
the effect systems:</p>

<pre>
<strong>axiom</strong> writable(int*);
<strong>axiom</strong> readable(int*);

<span class="hljs-keyword">int</span>* allocate()  [[post <span class="hljs-string">r:</span> writable(r)]]; 
<span class="hljs-keyword">int</span>* fill(<span class="hljs-keyword">int</span>* p) [[<span class="hljs-string">pre:</span> writable(p)] [[post <span class="hljs-string">r:</span> readable(r)]];
<span class="hljs-keyword">void</span> read(<span class="hljs-keyword">int</span>* p) [[<span class="hljs-string">pre:</span> readable(p)]];
<span class="hljs-keyword">void</span> deallocate(<span class="hljs-keyword">int</span>* p) [[<span class="hljs-string">pre:</span> writable(p)]];
</code></pre>

<p> In this example, we use keyword <code>axiom</code> as proposed in 
    <a href="https://isocpp.org/files/papers/P2176R0.html" 
       title="Andrzej Krzemieński, &ldquo;A different take on inexpressible conditions&rdquo;">[P2176R0]</a>.
    With this capability, one can build a new kind of tool for performing
    Type and Effect analysis: one that is not tied to a fixed set of 
    annotations, but can be taught to recognize arbitrary effect systems. 
    Given this use case &mdash; guiding type an effect static analysis &mdash; the 
    attribute-like syntax looks natural.</p>

<p> The desire to support something like this has been reflected in 
    <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1995r0.html">[P1995]</a>
	as the following use cases:
	</p>

<ul>
  <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1995r0.html#api.express.unimplementable">api.express.unimplementable</a>,</li>
  <li><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1995r0.html#dev.tooling">dev.tooling</a>.</li>
</ul>



<h2><a id="apr" class="sect">Appertaining to function type <span class="link">{apr}</span></a></h2>


<p>One argument against the attribute-like syntax, is that:</p>
<ol>
<li>the position they are at means for attributes that they appertain to function type, and</li>
<li>they do not appertain to function type.</li>
</ol>
<p>In order to validate this claim we would have to have a clear 
criterion for what qualifies as "appertaining to function type". The C++
 or C Standards do not give us an answer. We could reach to non-standard
 attributes. One case highlighted by Aaron Ballman is a vendor-specific
 attribute <code>[[gnu::fastcall]]</code>:</p>

<pre><code class="lang-c++"><span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">func</span>(<span class="hljs-params"><span class="hljs-keyword">int</span> i</span>) [[gnu::fastcall]]</span>;

<span class="hljs-function"><span class="hljs-keyword">int</span> <span class="hljs-title">main</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">void</span> (*fp)(<span class="hljs-keyword">int</span>) = func; <span class="hljs-comment">// error: type mismatch</span>
}
</code></pre>

<p>See the Compiler Explorer example: <a href="https://godbolt.org/z/3YzGb897f">https://godbolt.org/z/3YzGb897f</a>.
 This illustrates that this specific attribute changes the type of the 
function
it appertains to. But is it a general rule? Affecting the Effect system 
could be a natural generalization of extending the type system.</p>

<p> One practical criterion for appertaining to function type is if we 
can use the same attribute to declare the function type rather than a 
function:</p>

<pre>using AllocFun = void*(size_t s) [[pre: c &gt; 0u]][[post r: r != nullptr]];

AllocFun quickAlloc, smartAlloc; <em>// two functions with contract annotations?</em>
</pre>




<h2><a id="met" class="sect">Annotations on annotations <span class="link">{met}</span></a></h2>


<p> While preconditions feel like annotations on functions (they do not affect semantics of 
    "contract-correct" programs"), they themselves require to be annotated with some hints,
    such as that the predicate in the precondition is more expensive to evaluate than the function
    guarded by the precondition, or that a precondition annotation is new and is as likely to be incorrect
    as the code that it is guarding.
    </p> 
    
<p> Such "annotations" could naturally be expressed as attributes appertaining to preconditions.
    However, this becomes impossible when 
    preconditions themselves look like attributes: you cannot have an
 attribute appertain to an attribute. This problem does not exist if
a different syntax is used for contract annotations. The following, is 
an example taken from  <a href="https://isocpp.org/files/papers/P2461R0.pdf">[P2461]</a>:</p>

<pre>void store(P* p)
  pre{p != nullptr}
  [[audit]] pre{p-&gt;is_square()};
</pre>

<p> If attribute-like syntax is used for contract annotations, we would have to invent a new,
    unprecedented, syntax for annotating annotations: </p>

<pre>int get_val()
  [[post audit new val: good(val)]]    <em>// maybe like this</em>
  [[post val: fine(val); audit, new]]; <em>// or maybe like this</em>
</pre>



<h2><a id="rfl" class="sect">Detectability in reflection <span class="link">{rfl}</span></a></h2>


<p> It is possible that we might want in the future to inspect contract annotations through reflection.
    The question is: should things declared through attributes (or things pretending to be attributes)
    be detectable through reflection?</p>



<h2><a id="col" class="sect">The usage of colon <span class="link">{col}</span></a></h2>


<p> Currently the syntax for <em>attribute-specifier</em> uses colon for separating the <em>attribute-using-prefix</em>
    from namespace-less attributes:</p>

<pre>[[using clang: not_tail_called, optnone]] int f(int i);
</pre>

<p> Re-using colon in post-/pre-condition annotations would overload the meaning of the colon:</p>

<pre>upsell greatest_negotiable_upsell(list const&amp; l)
  [[post gnu: l.contains(gnu)]]
  [[using gnu: fastcall]];
</pre>

<p> The above example also illustrates that the presence of the colon alone cannot be used 
    to easily tell apart contract annotations and <em>attribute-specifier</em>s.</p>



<h2><a id="end" class="sect">Conclusion <span class="link">{end}</span></a></h2>


<p>
    The <em>semantic ignorability</em> property of C++ attributes
    is compatible with contract annotations and their two translation modes.
    However, contract annotations are not compatible with the <em>syntactic ignorability</em>
    preferred in WG14 for C attributes. Thus, while the attribute-like syntax
    would be a relatively good fit for C++ it would not necessarily be so for C.

    Moreover, contract annotations completely disregard the syntactic rules of
    attributes: appertainment, aggregation, comma-separation. If we adapted
    the attribute-like syntax, we would get two noticeably different features
    sharing the notion of optionality reflected in the double square brackets.
</p>




<h2><a id="ack" class="sect">Acknowledgments <span class="link">{ack}</span></a></h2>

<p> Jens Maurer and Aaron Ballman offered substantial feedback on the intuition behind
    the attribute notation. Tom Honermann and Timur Doumler reviewed the document and offered a substantial feedback.
    </p>


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


<ul>

  <li>[DnE] — Bjarne Stroustrup,
      "The Design and Evolution of C++", <br>
      <a href="https://www.stroustrup.com/dne.html">Addison-Wesley, ISBN 0-201-54330-3</a>.
      </li>
 
  <li>[STROUSTRUP] — Bjarne Stroustrup,
      "Wrapping C++ Member Function Calls" <br>
      (<a href="https://www.stroustrup.com/wrapper.pdf">https://www.stroustrup.com/wrapper.pdf</a>).
      </li>
      
  <li>[N1962] — Lawrence Crowl, Thorsten Ottosen,
      "Proposal to add Contract Programming to C++ (revision 4)" <br>
      (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1962.html">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1962.html</a>).
      </li>
   
  <li>[N4944] — Thomas Köppe,
      "Working Draft, Standard for Programming Language C++" <br>
      (<a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4944.pdf">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4944.pdf</a>).
      </li>
  <!-- <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/n4944.pdf" 
          title="Thomas Köppe, &ldquo;Working Draft, Standard for Programming Language C++&rdquo;">[N4944]</a>
   -->
   
  <li>[P0465] — Lisa Lippincott,
      "Procedural function interfaces" <br>
      (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0465r0.pdf">
          http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0465r0.pdf</a>).
      </li>
      
  <li>[P0542] — 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>
	  
  <li>[P1774R8] — Timur Doumler,
      "Portable assumptions" <br>
      (<a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1774r8.pdf">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1774r8.pdf</a>).
      </li>
  <!-- <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1774r8.pdf" 
          title="Timur Doumler, &ldquo;Portable assumptions&rdquo;">[P1774R8]</a>
   -->

  
  <li>[P1893] — Andrew Tomazos,
      "Proposal of Contract Primitives" <br>
      (<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1893r0.pdf">
          http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1893r0.pdf</a>).
      </li>
	  
  <li>[P2176R0] — Andrzej Krzemieński, "A different take on inexpressible conditions" <br>
      (<a href="https://isocpp.org/files/papers/P2176R0.html">https://isocpp.org/files/papers/P2176R0.html</a>).
      </li>
  <!-- <a href="https://isocpp.org/files/papers/P2176R0.html" 
          title="Andrzej Krzemieński, &ldquo;A different take on inexpressible conditions&rdquo;">[P2176R0]</a>
   -->
	  
  <li>[P2388R4] — Andrzej Krzemieński, Gašper Ažman,
      "Minimum Contract Support: either <em>No_eval</em> or <em>Eval_and_abort</em>" <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>[P2461] — 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/p2461r0.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p2461r0.pdf</a>).
      </li>
  
  <li>[P2552R2] — Timur Doumler,
      "On the ignorability of standard attributes" <br>
      (<a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2552r2.pdf">https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2552r2.pdf</a>).
      </li>
  <!-- <a href="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2023/p2552r2.pdf" 
          title="Timur Doumler, &ldquo;On the ignorability of standard attributes&rdquo;">[P2552R2]</a>
  -->
  
  
	  
</ul>








</body></html>