1. ホーム
  2. c++

[解決済み] as-if "ルールとは何ですか?

2023-01-30 11:14:14

質問

タイトルの通りです。

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

典型的な答えが返ってきます。

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

時々、私たちはある実装から、このルールに起因する振る舞いを受け取り続けています。多くの場合、間違っています。

では、このルールはいったい何なのでしょうか?規格はこのルールをセクションまたは段落として明確に言及していませんので、何がこのルールの適用範囲になるのでしょうか。

私には、規格で詳しく定義されていないグレーゾーンのように思えます。どなたか、標準からの参照を引用して、詳細を説明していただけませんか。

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

どのように解決するのですか?

とは何ですか? として というルールはありますか?

"のことです。 として ルールは、基本的に、実装が合法的な C++ プログラムに対してどのような変換を行うことができるかを定義しています。要するに、プログラムの " に影響を与えないすべての変換が許可されます。 観察可能な動作 正確な定義については後述します)。

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


規格のどこにこのルールがあるのですか?

C++11 標準では、" が導入されています。 as-if という規則が導入されました。

この国際規格の意味記述は,パラメタ化された非決定論的抽象機械を定義する。 マシンを定義しています。この国際規格は,適合する実装の構造に対して,何の要求も行わない。 特に,抽象機械の構造をコピーしたりエミュレートしたりする必要はない。むしろ,適合する をエミュレートすることが要求されます。 観測可能な動作 をエミュレートする必要があります。 をエミュレートする必要があります。

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

<ブロッククオート

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


具体的にはどのようなことが定められているのでしょうか。

1.9/5項で、さらに規定されています。

適合する実装 整形されたプログラムを実行する と同じ観測可能な振る舞いを生成しなければならない。 抽象機械の対応するインスタンスの実行可能な動作の一つとして、同じプログラム と同じ入力 . しかし,そのような実行が未定義の操作を含んでいる場合,この国際規格は,その入力でそのプログラムを実行する実装に何らの要求も課さない。 しかし,そのような実行に未定義の操作が含まれる場合,この国際規格は,そのプログラムをその入力で実行する実装に何の要件も課さない(最初の未定義の操作の前の操作に関しても)。 最初の未定義の操作の前の操作に関しても)。

この制約は次の場合に適用されることを強調する価値があります。 "整形されたプログラムを実行するときです。 のみに適用され、未定義の動作を含むプログラムを実行した場合に起こりうる結果には制約がないことを強調しておきます。このことは、1.9/4項でも明示されています。

この国際規格では、他のある種の操作については未定義とされている(例えば この国際規格では、他のある操作は未定義とされています(例えば、constオブジェクトを変更しようとしたときの効果)。[ 注 この国際規格は,未定義の動作を含むプログラムの動作に対して,いかなる要件も課さない。 未定義の動作を含むプログラムの動作について、いかなる要件も課さない。 . -注を終了する]。

最後に、"の定義について。 観測可能な動作 の定義について、1.9/8項は以下のようになります。

適合する実装に対する最低限の要件は、以下の通りです。

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

- プログラムの終了時に、ファイルに書き込まれたすべてのデータは、抽象的意味論に従ったプログラムの実行が生み出すであろう可能な結果のうちの1つと同一でなければならない。 と同じでなければならない。

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

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


このルールが適用されない状況はあるのでしょうか?

私の知る限り、" の唯一の例外は以下の通りです。 として これは、クラスのコピー コンストラクタ、移動コンストラクタ、またはデストラクタが副作用を持つ場合でも許可されます。この正確な条件は、パラグラフ12.8/31で指定されています。

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