|
191 | 191 | <p class="text-right"><small> |
192 | 192 | 最終更新日時: |
193 | 193 | <time itemprop="datePublished" class="js-local-time" |
194 | | - datetime="2026-09-04T11:37:58+09:00"> |
195 | | - 2026年09月04日 11時37分58秒 (JST) |
| 194 | + datetime="2026-10-14T15:57:16+09:00"> |
| 195 | + 2026年10月14日 15時57分16秒 (JST) |
196 | 196 | </time> |
197 | 197 | <br/> |
198 | 198 | <span itemprop="author" itemscope itemtype="http://schema.org/Person"> |
@@ -552,10 +552,7 @@ <h4>quick-enforce(高速強制)</h4> |
552 | 552 | <p><code>quick-enforce</code>セマンティクスは<a class="cpprefjp-defined-word" data-desc="boolを返す関数・関数オブジェクト。predicate">述語</a>を評価して契約違反を識別する。契約違反が発生した場合、契約違反ハンドラを呼び出さずに、即座にプログラムを<a class="cpprefjp-defined-word" data-desc="処理系定義の動作。処理系によって事前に定めた動作をする" href="../../implementation-compliance.html#dfn-implementation-defined-behavior">実装定義</a>の方法で終了する。これはチェックセマンティクスであり、終了セマンティクスでもある。<code>quick-enforce</code>は、契約違反ハンドラのオーバーヘッドを避けるため、パフォーマンスが重要な状況で有用である。</p> |
553 | 553 | <h4>評価セマンティクスの選択</h4> |
554 | 554 | <p>契約アサーションの個別の評価に対してどの評価セマンティクスが使用されるかを選択するメカニズムは<a class="cpprefjp-defined-word" data-desc="処理系定義の動作。処理系によって事前に定めた動作をする" href="../../implementation-compliance.html#dfn-implementation-defined-behavior">実装定義</a>である。コンパイル時オプション、実行時設定、またはその組み合わせで指定できる。</p> |
555 | | -<p>GCCでの例:</p> |
556 | | -<p><div class="codehilite"><pre><span></span><code>g++<span class="w"> </span>-std<span class="o">=</span>c++26<span class="w"> </span>-fcontracts<span class="w"> </span>-fcontract-semantic<span class="o">=</span>observe<span class="w"> </span>main.cpp |
557 | | -</code></pre></div> |
558 | | -</p> |
| 555 | +<p>処理系ごとの指定方法は、<a href="#compile-options">コンパイルオプション</a>を参照。</p> |
559 | 556 | <h4>契約<a class="cpprefjp-defined-word" data-desc="boolを返す関数・関数オブジェクト。predicate">述語</a>のチェック</h4> |
560 | 557 | <p>チェックセマンティクス(<code>observe</code>、<code>enforce</code>、<code>quick-enforce</code>)では、<a class="cpprefjp-defined-word" data-desc="boolを返す関数・関数オブジェクト。predicate">述語</a>が評価され、<code>bool</code>に文脈変換される。<a class="cpprefjp-defined-word" data-desc="boolを返す関数・関数オブジェクト。predicate">述語</a>が<code>true</code>に評価されると、契約違反は識別されない。<a class="cpprefjp-defined-word" data-desc="boolを返す関数・関数オブジェクト。predicate">述語</a>が<code>false</code>に評価されるか、<a class="cpprefjp-defined-word" data-desc="boolを返す関数・関数オブジェクト。predicate">述語</a>の評価が<a class="cpprefjp-defined-word" data-desc="問題が発生したときに、現在実行位置を過去に通過・記録した位置に戻し、文脈情報を添えて紐づけられた処理(例外ハンドラー)を呼び出す仕組み。またはその事態">例外</a>で終了すると、契約違反が識別される。</p> |
561 | 558 | <p><a class="cpprefjp-defined-word" data-desc="boolを返す関数・関数オブジェクト。predicate">述語</a>の評価がスタックを通じて制御を返さない他の結果(終了、無限ループ、<code>longjmp</code>の呼び出しなど)が発生した場合、他のC++式の評価時と同様に処理される。</p> |
@@ -709,6 +706,59 @@ <h4>assert マクロとの違い</h4> |
709 | 706 | <li><strong><a class="cpprefjp-defined-word" data-desc="関数等の意味論を構成する要素の1つ。Postconditions。関数を実行後に満たされている条件。契約属性の`[[ensures]]`に相当">事後条件</a></strong>: 契約プログラミングは<a class="cpprefjp-defined-word" data-desc="関数等の意味論を構成する要素の1つ。Postconditions。関数を実行後に満たされている条件。契約属性の`[[ensures]]`に相当">事後条件</a>を簡潔に記述できるが、<code>assert</code>マクロでは困難</li> |
710 | 707 | <li><strong>標準化</strong>: 契約プログラミングはC++標準の一部であり、<code>assert</code>はCから継承されたマクロである</li> |
711 | 708 | </ul> |
| 709 | +<h2><a href="#compile-options" id="compile-options">コンパイルオプション</a></h2> |
| 710 | +<p>契約アサーションをどの評価セマンティクスで評価するかは<a class="cpprefjp-defined-word" data-desc="処理系定義の動作。処理系によって事前に定めた動作をする" href="../../implementation-compliance.html#dfn-implementation-defined-behavior">実装定義</a>であり、処理系が提供するコンパイルオプションで指定する。</p> |
| 711 | +<h3>GCC</h3> |
| 712 | +<table border="1" bordercolor="#888" style="border-collapse:collapse"> |
| 713 | +<thead> |
| 714 | +<tr> |
| 715 | +<th>オプション</th> |
| 716 | +<th>説明</th> |
| 717 | +</tr> |
| 718 | +</thead> |
| 719 | +<tbody> |
| 720 | +<tr> |
| 721 | +<td><code>-fcontracts</code></td> |
| 722 | +<td>契約プログラミング機能を有効にする。<code>-std=c++26</code>を指定した場合は暗黙に有効となる</td> |
| 723 | +</tr> |
| 724 | +<tr> |
| 725 | +<td><code>-fcontract-evaluation-semantic=</code></td> |
| 726 | +<td>評価セマンティクスを<code>ignore</code>、<code>observe</code>、<code>enforce</code>、<code>quick_enforce</code>のいずれかに指定する。デフォルトは<code>enforce</code></td> |
| 727 | +</tr> |
| 728 | +<tr> |
| 729 | +<td><code>-fcontracts-client-check=</code></td> |
| 730 | +<td>呼び出し側でチェックするアサーションを<code>none</code>、<code>pre</code>、<code>all</code>のいずれかに指定する。デフォルトは<code>none</code></td> |
| 731 | +</tr> |
| 732 | +<tr> |
| 733 | +<td><code>-fcontracts-definition-check=</code></td> |
| 734 | +<td>定義側でのチェックを<code>on</code>、<code>off</code>のいずれかに指定する。デフォルトは<code>on</code></td> |
| 735 | +</tr> |
| 736 | +<tr> |
| 737 | +<td><code>-fcontract-checks-outlined</code></td> |
| 738 | +<td><a class="cpprefjp-defined-word" data-desc="関数等の意味論を構成する要素の1つ。Preconditions。関数呼び出し時に満たされていると関数が想定する条件。満たさなければ未定義の動作。契約属性の`[[expects]]`に相当">事前条件</a>・<a class="cpprefjp-defined-word" data-desc="関数等の意味論を構成する要素の1つ。Postconditions。関数を実行後に満たされている条件。契約属性の`[[ensures]]`に相当">事後条件</a>のチェックを関数本体に展開せず、別の関数として切り出して呼び出す</td> |
| 739 | +</tr> |
| 740 | +<tr> |
| 741 | +<td><code>-fcontract-disable-optimized-checks</code></td> |
| 742 | +<td><code>-fcontract-checks-outlined</code>で切り出した関数に対する最適化を抑制する</td> |
| 743 | +</tr> |
| 744 | +<tr> |
| 745 | +<td><code>-fcontracts-conservative-ipa</code></td> |
| 746 | +<td>翻訳単位ごとに評価セマンティクスが異なりうることを前提として、インライン関数に対する手続き間解析を抑制する。デフォルトで有効</td> |
| 747 | +</tr> |
| 748 | +</tbody> |
| 749 | +</table> |
| 750 | +<p><div class="codehilite"><pre><span></span><code><span class="c1"># 契約アサーションをobserveセマンティクスで評価する</span> |
| 751 | +g++<span class="w"> </span>-std<span class="o">=</span>c++26<span class="w"> </span>-fcontracts<span class="w"> </span>-fcontract-evaluation-semantic<span class="o">=</span>observe<span class="w"> </span>main.cpp |
| 752 | +</code></pre></div> |
| 753 | +</p> |
| 754 | +<ul> |
| 755 | +<li>評価セマンティクスは、コンパイル時に翻訳単位ごとに決定される。契約アサーションごとに指定する方法や、実行時に切り替える方法は提供されていない<ul> |
| 756 | +<li>翻訳単位ごとに異なるセマンティクスを指定した場合、関数を定義した翻訳単位のセマンティクスが適用される</li> |
| 757 | +</ul> |
| 758 | +</li> |
| 759 | +<li>契約違反ハンドラのデフォルトの実装は<code>libstdc++exp</code>ライブラリが提供する。このライブラリは、コマンドラインに<code>-fcontracts</code>を指定した場合に自動的にリンクされる。<code>-std=c++26</code>によって暗黙に有効化した場合はリンクされないため、<code>-lstdc++exp</code>オプションを指定する必要がある</li> |
| 760 | +<li>GCC 15以前の<code>-fcontracts</code>は、C++26に採用されたP2900とは異なる仕様 (N4820、P1332、P1429) の実験的な実装であり、<code>-fcontract-build-level</code>や<code>-fcontract-role</code>などの別のオプションを提供していた</li> |
| 761 | +</ul> |
712 | 762 | <h2>例</h2> |
713 | 763 | <h3>基本的な使用例</h3> |
714 | 764 | <p><div class="yata" id="613db261414e8c27c152a3bb92ec08fd5a279c2e"><div class="codehilite"><pre><span></span><code><span class="cp">#include <a href="../../reference/contracts.html"><contracts></a></span> |
|
0 commit comments