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


89

タイトルの通り、

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

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

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

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

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


2
抽象マシンを指します。
Alexey Frunze 2013年

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

@AlexeyFrunze「抽象的な機械を指します」「抽象的な機械」がツールではなく目的であり、適合という意味では無関係であることを指します。これは、仕様ツールである「抽象的な」が実際ではないためです。
-curiousguy

回答:


98

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つと同一でなければなりません。

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

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


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

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

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


2
私はこの引用を見ました。明確ではないのは、観察可能な行動の定義です。観察可能な行動として正確に何が当てはまるのですか?コピー省略がas-ifルールの例外であることはよく知られていることであり、私の質問の一部ではありません。
Alok Save 2013

2
@AlokSave:C標準では、「揮発性オブジェクトへのアクセス、オブジェクトの変更、ファイルの変更、またはこれらの操作のいずれかを実行する関数の呼び出しはすべて副次作用」と見なされます。おそらく、C ++標準には同等のものがあります。非公式には、「外界との相互作用を変えるもの」だと思います。
Oliver Charlesworth 2013年

1
抽象マシンの状態を変更する動作(つまり、渡された変数またはグローバル変数を変更したり、I / Oデバイスに読み書きしたりする動作)。
Mats Petersson 2013年

1
これは、その後何も観察されない限り、何もしない無限ループの削除が許可されることを意味しますか?
ハロルド2013年

5
特に注意すべき点は、法的プログラムにのみ適用されることです。未定義の動作を呼び出すものは、明示的に対象外です。
フォンブランド2013年

15

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

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

  2. [...]

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

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

     

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


-1

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

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

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

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

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

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

概要:

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

人々が私が間違っていると信じており、明確な「まるでルール」がある場合、その「ルール」のないC ++(方言)のバリアントを記述しようとしないのはなぜですか。C ++仕様はそれなしでどういう意味ですか?コンパイラが適合しているかどうかを判断することは絶対に不可能です。または、適合を定義することもできます。
curiousguy
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.