web-dev-qa-db-ja.com

「as-if」ルールとは正確には何ですか?

タイトルの通り、

「as-if」ルールとは正確には何ですか?

典型的な答えは次のとおりです。

プログラムの監視可能な動作を変更しないすべてのコード変換を許可するルール

時々、このルールに起因する特定の実装から動作を取得し続けます。何度も間違って。つまり、このルールは正確には何ですか。この規格では、この規則がセクションまたは段落として明確に言及されていないため、この規則の範囲に正確に該当するものは何ですか?私には、標準で詳細に定義されていない灰色の領域のように見えます。誰かが標準からの参照を引用して詳細を詳しく説明できますか?

注:これはCとC++の両方としてタグ付けします。これは、両方の言語に関連するためです。

87
Alok Save

as-if」ルールとは何ですか?

as-if」ルールは、基本的に、実装が正当なC++プログラムで実行できる変換を定義します。つまり、プログラムの「観察可能な動作」(正確な定義については以下を参照)に影響を与えないすべての変換が許可されます。

目標は、プログラムの動作が抽象マシンに関してC++標準で指定されたセマンティクスに準拠している限り、最適化を実行する自由を実装に与えることです。


規格はこのルールをどこで導入しますか?

C++ 11標準では、1.9/1項に「as-if」ルールが導入されています。

この国際標準の意味論的記述は、パラメーター化された非決定論的な抽象マシンを定義しています。この国際規格は、適合実装の構造に要件を課していません。特に、抽象マシンの構造をコピーまたはエミュレートする必要はありません。むしろ、以下に説明するように、抽象マシンの観察可能な動作をエミュレート(のみ)するには、準拠する実装が必要です。

また、説明の脚注には以下が追加されています。

この規定は、「as-if」ルールと呼ばれることもあります。実装は、結果が要件に従っているかのようである限り、実装がこの国際規格の要件を自由に無視できるため、プログラムの観察可能な動作から判断できます。たとえば、実際の実装では、その値が使用されておらず、プログラムの観察可能な動作に影響を与える副作用がないことが推定できる場合、式の一部を評価する必要はありません。


ルールは正確に何を義務付けていますか?

1.9/5項では、さらに次のことを指定しています。

準拠する実装整形式プログラムを実行すると、抽象の対応するインスタンスの可能な実行の1つと同じ観察可能な動作が生成されます。同じプログラムと同じ入力を持つマシン。ただし、そのような実行に未定義の操作が含まれている場合、この国際規格では、その入力を使用してそのプログラムを実行する実装に要件はありません(最初の未定義の操作の前の操作についても同様)。

この制約は、「整形式プログラムの実行」の場合にのみ適用され、未定義の動作を含むプログラムを実行した場合の考えられる結果は、拘束されていません。これは、1.9/4項でも明示されています。

他の特定の操作は、この国際標準では未定義として記述されています(たとえば、constオブジェクトを変更しようとした場合の影響)。 [注:この国際標準は、未定義の動作を含むプログラムの動作に要件を課していません。 —エンドノート]

最後に、「観察可能な動作」の定義に関して、1.9/8項は次のようになります。

適合実装の最小要件は次のとおりです。

—揮発性オブジェクトへのアクセスは、抽象マシンのルールに従って厳密に評価されます。

—プログラムの終了時に、ファイルに書き込まれたすべてのデータは、抽象的なセマンティクスに従ってプログラムを実行した場合に生じる可能性のある結果の1つと同じになります。

—対話型デバイスの入力と出力のダイナミクスは、プログラムが入力を待機する前に、プロンプト出力が実際に配信されるような方法で行われます。対話型デバイスを構成するものは実装定義です。

これらをまとめて、プログラムの観察可能な動作と呼びます。 [:抽象と実際のセマンティクス間のより厳密な対応は、各実装によって定義される場合があります。 —end note]


このルールが適用されない状況はありますか?

私の知る限りでは、「as-if」ルールの唯一の例外は、コピー/移動省略です。これは、コピーコンストラクターであっても許可されます、移動コンストラクタ、またはクラスのデストラクタには副作用があります。これの正確な条件は、12.8/31項で指定されています。

特定の基準が満たされると、実装はクラスオブジェクトのコピー/移動の構築を省略できますコピー/移動操作用に選択されたコンストラクターやオブジェクトのデストラクタに副作用がある場合でも =。 [...]

93
Andy Prowl

C11では、ルールはその名前で呼び出されることはありません。ただし、CはC++と同様に、抽象マシンの観点から動作を定義します。 as-ifルールは C11 5.1.2.3p4およびp6 にあります。

  1. 抽象マシンでは、すべての式がセマンティクスで指定されたとおりに評価されます。 実際の実装では、その値が使用されておらず、必要な副作用が生じていない(関数の呼び出しや揮発性オブジェクトへのアクセスによるものも含む)と推定できる場合、式の一部を評価する必要はありません。 )。

  2. [...]

  3. 適合実装の最小要件は次のとおりです。

    • volatileオブジェクトへのアクセスは、抽象マシンのルールに従って厳密に評価されます。
    • プログラムの終了時に、ファイルに書き込まれたすべてのデータは、抽象的なセマンティクスに従ってプログラムを実行した結果と同じになります。
    • 7.21. で指定されているように、インタラクティブデバイスの入力と出力のダイナミクスが発生します。これらの要件の意図は、プログラムが入力を待機する前にプロンプ​​トメッセージが実際に表示されるように、バッファなしまたはラインバッファ付きの出力をできるだけ早く表示することです。

    これはプログラムの観察可能な動作です。

15
Antti Haapala

C、C++、Ada、Java、SML ...プログラムの(通常は多くの可能性のある、非決定論的な)動作を記述することで指定された任意のプログラミング言語(I/Oポートでの一連の対話に公開) 、明確なas-ifルールはありません

distinctルールの例は、ゼロによる除算が例外を発生させる(Ada、Caml)か、null逆参照が例外を発生させる(Java)ことを示すルールです。ルールを変更して何かを指定することもできますelseすると、異なる言語になります(一部の人々はむしろ「方言」(*)と呼ぶでしょう)明確なルールがありますプログラミング言語のいくつかの明確な使用法を指定する明確な文法規則のようなsome構文構造。

(*)一部の言語学者による方言は、「軍隊」を伴う言語です。その意味では、委員会やコンパイラエディタの特定の業界を持たないプログラミング言語を意味する可能性があります。

as-ifルールは明確なルールではありません;それは特にプログラムをカバーしておらず、どのような方法でも議論、削除、または変更できるルールでさえありません:いわゆる「ルール」は、プログラムのセマンティクスが定義されていることを単に繰り返します。プログラムの実行と「外部」の世界との目に見える相互作用の観点から、移植可能に(普遍的に)のみ定義できます。

外界は、I/Oインターフェース(stdio)、GUI、または純粋なアプリケーション言語の結果の値を出力する対話型インタープリターでさえあります。 CおよびC++には、揮発性オブジェクトへの(漠然と指定された)アクセスが含まれます。これは、特定のポイントの一部のオブジェクトは、ABI(アプリケーションバイナリインターフェース)に厳密に従ってメモリ内で厳密に表現する必要があることを示すもう1つの方法です。

実行のトレースの定義は、可視または観察可能な動作とも呼ばれ、「as-ifルール」の意味を定義します。 as-ifルールtriesで説明しますが、そうすることで、実装に余裕を与える追加のセマンティックルールであるという表現を与えるため、説明が明確になるよりも混乱します。

概要:

  • いわゆる「as-ifルール」は、実装の制約を緩和しません。
  • 目に見える動作(外部の世界との相互作用のために構成された実行トレース)で指定されたプログラミング言語のas-ifルールを削除して、明確な方言を取得することはできません。
  • 可視動作に関して指定されていないプログラミング言語には、as-ifルールを追加できません。
0
curiousguy