3

ここでの質問に対する私の答えでは、returnステートメントと同じ行のグローバル変数で接尾辞++が使用されたときに何が起こったのかを説明しました。

C11の有益な付録Cは、aの直後にシーケンスポイントがあり、シーケンスポイントreturnに関するテキストが見つからない規範的な第6.8.6.4章を参照していると述べています。

returnC標準のどこに、ステートメントの後にシーケンスポイントがあることを示す規範的なテキストを見つけることができますか?

(私は、特別な場合として、7.1.4 / 3で、ライブラリ関数についてこれを示す規範的なテキストのみを見つけました。)

4

2 に答える 2

4

C 2011(draft n1570)6.8 4:「次のそれぞれは完全な式です:… returnステートメントの(オプションの)式。完全な式の評価と、評価される次の完全な式の評価の間には、シーケンスポイントがあります。」</ p>

したがって、技術的には、シーケンスポイントはリターンの後ではなく、リターンの式の評価と次の式の間にあります。が最初に0のときに呼び出されるこのコードについて考えてみます。a

int a = 0;

int Foo(void) { return a++; }

void Bar(void)
{
    int b = Foo() + a;
    …
}

では、またはが最初に評価されるFoo() + aかどうFoo()aは指定されていません。両方の潜在的なルール(リターン後のシーケンスポイントとリターンの式と次の完全な式の間のシーケンスポイント)に照らして、両方の順序を検討します。実装がa最初に行う場合は、次のことを行う必要があります。

a
Sequence point
Foo()
+

次に、他の完全な式が続くので、どちらの規則でも、シーケンスポイントがあり、このコードは、私たちに関する限り、どちらの方法でも同じです。その結果b、0に設定されます。

実装が最初に実行する場合、 「リターンFoo()後のシーケンスポイント」ルールを使用して、実装は次のことを実行する必要があります。

Sequence point
Foo()
Sequence point
a
+

このコードには、動作が定義されているはずです。aの副作用によって増分され、アクセスさFooれる前に完了してから実行されます。結果は1に設定されます。この「リターン後のシーケンスポイント」ルールでは結果は0または1になる可能性がありますが、2つの順序のどちらが使用されるかは単に指定されていません。動作は完全に未定義ではありません。a+a

ただし、実装が最初に実行し、「リターンの式と次の完全な式Foo()の間のシーケンスポイント」という標準のCルールを使用する場合、次のようになります。

Sequence point
Foo()
???
a
???
+
???

「???」必要なシーケンスポイントが存在する可能性のある場所(戻り後、次の完全な式の前)にマークを付けます。この場合、の値はでアクセスおよび変更さaれる可能性があり、間にシーケンスポイントはありません。それは未定義の動作です。aFoo()

したがって、「リターンの式の後、次の完全な式の前のシーケンスポイント」というルールは、「リターンの直後のシーケンスポイント」とは異なります。この例では、最初の動作は未定義であり、2番目の動作は未定義です。

于 2013-03-26T13:04:23.537 に答える
4

私はあなたがあなたが探しているものを見つけるつもりはないと思います。no text regarding sequence points can be foundそれは本当です、それはセクション6.8p4によってのみ暗示されます。

セクション1.9(脚注11)のC ++標準(ISO / IEC 14882:2003)は、復帰後のシーケンスポイントがC標準のどこにも明示的に記述されていないという事実を述べています。

11)関数returnのシーケンスポイントはISO Cで明示的に指定されておらず、完全な式のシーケンスポイントと冗長であると見なすことができますが、C++ではさらに明確にすることが重要です。C + +では、例外のスローなど、呼び出された関数が実行を終了できる方法が他にもあります。

于 2013-03-26T13:14:24.010 に答える