私はグローバル変数var
と関数foo
を持っています。Cでポストインクリメントを使用して変数を返す
long foo(){
return var++;
}
感謝を:C規格は(私はC99を使用してコンパイルしています)私が実行しようとした場合var
に何が起こるかと言う場合、私は思ったんだけど(私はそれが悪い習慣だ知っているが、時にはそれが避けられないのです)。
私はグローバル変数var
と関数foo
を持っています。Cでポストインクリメントを使用して変数を返す
long foo(){
return var++;
}
感謝を:C規格は(私はC99を使用してコンパイルしています)私が実行しようとした場合var
に何が起こるかと言う場合、私は思ったんだけど(私はそれが悪い習慣だ知っているが、時にはそれが避けられないのです)。
短い答え:
それはグローバルvar
をインクリメント直後、その後var
のコピーを返します。
長い答え:接尾辞の
C11 6.5.2.4
」結果が++演算子は、オペランドの値であり、副作用 として、オペランドオブジェクトの値です。増分.. "。/-/ 結果の値の計算は、オペランドの格納された値を更新する副作用( )の前に順序付けられます。
標準5.1.2.3「プログラムの実行は、」プログラムがシーケンスポイントに遭遇する前に、すべての副作用が評価されていなければならないことを指定します。 (多くのシーケンスポイントはhereです)。
return
ステートメント(C11 6.8/4)の後にシーケンスポイントがあります。
つまり、式var++
は、main()内のコードが続行される前に完全に評価されることが保証されています。
あなたのマシンコードは、この擬似コードのようになります。
var
を増やし
var
のローカルコピー(または中などを登録します)サブルーチンから。var
"を使用してください。代わりにプレフィックス増分を使用していた場合、増分操作はコピーが保存される前にシーケンス化されていました。
上記の「マシンコード」は、グローバル変数の++がスレッドセーフではない理由を示していると言えるでしょう。 「ストアコピー」と「増加」との間のコンテクストスイッチは、予期しないプログラム動作を引き起こす可能性があります。 – Lundin
foo()
は現在値var
を返し、var
は増加します。 var++
として
は、基本的にこのようなもので、ポストインクリメントである:あなたの代わりに++var
を使用している場合は、それが戻って前に変数をインクリメントするよう
long foo(){
long tmp = var;
var++;
return tmp;
}
が、それは(インクリメント値を返します。その値)。
古い値が返され、インクリメントされた値が格納されます。 –
はい。期待どおりに動作しているようです。私はそれが正しいと判断していないだけで、標準で判断すると思っています。 – mgoszcz2
グローバル変数と同じくらいうまくいきます。 –