11

私が今日C標準を読んだとき、それは副作用について述べています

揮発性オブジェクトへのアクセス、オブジェクトの変更、ファイルの変更、またはこれらの操作のいずれかを行う関数の呼び出しはすべて副作用です

そしてC++標準は言う

volatile glvalue (3.10) で指定されたオブジェクトへのアクセス、オブジェクトの変更、ライブラリ I/O 関数の呼び出し、またはこれらの操作のいずれかを実行する関数の呼び出しはすべて副作用です。

したがって、どちらも同じスカラー オブジェクトでシーケンス化されていない副作用が発生することを禁止しているため、C では次のことが許可されますが、C++ では未定義の動作になります。

int a = 0;
volatile int *pa = &a;

int b = *pa + *pa;

仕様を正しく読んでいますか?また、もしそうなら、その不一致の理由は何ですか?

4

1 に答える 1

1

この点に関して、C と C++ の間に有効な違いがあるとは思えません。順序付けの文言は異なりますが、最終結果は同じです。どちらも未定義の動作になります (ただし、C は評価が成功することを示しているようですが、結果は未定義です)。

C99 (申し訳ありませんが、C11 は手元にありません) では、段落 5.1.2.3.5 で次のように指定されています。

— シーケンス ポイントでは、以前のアクセスが完了し、後続のアクセスがまだ発生していないという意味で、揮発性オブジェクトは安定しています。

5.1.2.3.2 からの引用と組み合わせるとpa、 へのアクセスの少なくとも 1 つで、 の値が安定した状態にないことが示されpaます。これは、コンパイラがそれらを任意の順序で、1 回だけ、または同時に (可能であれば) 評価できるため、論理的に理にかなっています。ただし、実際には安定が何を意味するのかを定義していません。

C++11 では、1.9.13 で順序付けされていないオペレーションへの明示的な参照があります。次に、ポイント 15 は、同じオペランドに対するこのような順序付けされていない操作が定義されていないことを示します。未定義の動作は何かが起こることを意味する可能性があるため、おそらく C の不安定な動作よりも強力です。ただし、どちらの場合も、式の結果が保証されるわけではありません。

于 2012-10-14T15:03:12.650 に答える