<!DOCTYPE HTML>
<html>
<head>
	<title>Observe and ignore semantics in constant evaluation</title>

	<style>
	p {text-align:justify}
	li {text-align:justify}
	blockquote.note
	{
		background-color:#E0E0E0;
		padding-left: 15px;
		padding-right: 15px;
		padding-top: 1px;
		padding-bottom: 1px;
	}
	ins {color:#00A000}
	del {color:#A00000}
	</style>
</head>
<body>

<address align=right>
Document number: P3338R0
<br/>
Audience: EWG
<br/>
<br/>
<a href="mailto:ville.voutilainen@gmail.com">Ville Voutilainen</a><br/>

2024-06-23<br/>
</address>
<hr/>
<h1 align=center>Observe and ignore semantics in constant evaluation</h1>

<h2>Abstract</h2>

<p>This paper explains why the observe and ignore semantics are useful
  in constant evaluation, i.e. for contract assertions that are evaluated
  at translation time.
</p>

<h2>The long and short of it</h2>

<p>So, we start out with a function:
<blockquote><pre><code>int f(int x)
{
    if (x &lt; 0) // defensive check
      return -1;
    return x * 2; // a totally concocted example definition, in
reality much more complex
}
</code></pre></blockquote>
</p>

<p>
Okay, now we add a contract

<blockquote><pre><code>int f(int x) pre(x &gt;= 0)
{
    if (x &lt; 0) // defensive check
      return -1;
    return x * 2; // a totally concocted example definition, in
reality much more complex
}
</code></pre></blockquote>
</p>

<p>
Not all callers have necessarily accommodated the contract, and the
defensive check is still there. So callers that call with negative
numbers work fine. To find them, you evaluate the pre with the
'observe' semantic. Incorrect callers are incorrect, but an incorrect
call
is perfectly recoverable.
</p>

<p>Make it constexpr,

<blockquote><pre><code>constexpr int f(int x) pre(x &gt;= 0)
{
    if (x &lt; 0) // defensive check
      return -1;
    return x * 2; // a totally concocted example definition, in
reality much more complex
}
</code></pre></blockquote>
</p>

<p>
and nothing changes. Incorrect calls are recoverable. Evaluate the pre
with the 'observe' semantic, and your program compiles
fine. The defensive check protects the innocent.
</p>

<p>
And then, if you don't want any diagnostics, you compile with the
'ignore' semantic, and you don't even get a warning. Quite like
you wouldn't get any violation handler call with a run-time check.
</p>

<p>
Yes, to use such an approach effectively, you eventually want a label
that can mark a contract as "ignore or observe, but not enforce".
But it can be used without labels already.
</p>

</body>
</html>
