2013-03-25 5 views
6

私はグローバル変数varと関数fooを持っています。Cでポストインクリメントを使用して変数を返す

long foo(){ 
    return var++; 
} 

感謝を:C規格は(私はC99を使用してコンパイルしています)私が実行しようとした場合varに何が起こるかと言う場合、私は思ったんだけど(私はそれが悪い習慣だ知っているが、時にはそれが避けられないのです)。

+0

古い値が返され、インクリメントされた値が格納されます。 –

+0

はい。期待どおりに動作しているようです。私はそれが正しいと判断していないだけで、標準で判断すると思っています。 – mgoszcz2

+1

グローバル変数と同じくらいうまくいきます。 –

答えて

9

短い答え:

それはグローバルvarをインクリメント直後、その後varのコピーを返します。

長い答え:接尾辞の

C11 6.5.2.4

」結果が++演算子は、オペランドの値であり、副作用 として、オペランドオブジェクトの値です。増分.. "。/-/ 結果の値の計算は、オペランドの格納された値を更新する副作用( )の前に順序付けられます。

標準5.1.2.3「プログラムの実行は、」プログラムがシーケンスポイントに遭遇する前に、すべての副作用が評価されていなければならないことを指定します。 (多くのシーケンスポイントはhereです)。

returnステートメント(C11 6.8/4)の後にシーケンスポイントがあります。

つまり、式var++は、main()内のコードが続行される前に完全に評価されることが保証されています。

あなたのマシンコードは、この擬似コードのようになります。

  • は1
  • 戻るとグローバルvarを増やし

    • ストアスタック上varのローカルコピー(または中などを登録します)サブルーチンから。
    • "copy-of-var"を使用してください。

    代わりにプレフィックス増分を使用していた場合、増分操作はコピーが保存される前にシーケンス化されていました。

  • +0

    上記の「マシンコード」は、グローバル変数の++がスレッドセーフではない理由を示していると言えるでしょう。 「ストアコピー」と「増加」との間のコンテクストスイッチは、予期しないプログラム動作を引き起こす可能性があります。 – Lundin

    2

    foo()は現在値varを返し、varは増加します。 var++として

    4

    は、基本的にこのようなもので、ポストインクリメントである:あなたの代わりに++varを使用している場合は、それが戻って前に変数をインクリメントするよう

    long foo(){ 
        long tmp = var; 
        var++; 
        return tmp; 
    } 
    

    が、それは(インクリメント値を返します。その値)。

    関連する問題