1. ホーム
  2. c

[解決済み] i = (i, ++i, 1) + 1; は何をするのですか?

2022-04-22 05:17:59

質問

読み終えて この回答 未定義の動作とシーケンスポイントについて、小さなプログラムを書いてみました。

#include <stdio.h>

int main(void) {
  int i = 5;
  i = (i, ++i, 1) + 1;
  printf("%d\n", i);
  return 0;
}

出力は 2 . ああ、神よ!私はデクリメントが来るのを見ませんでした ここで何が起こっているのでしょうか?

また、上記のコードをコンパイルしているときに、こんな警告が出ました。

px.c:5:8: 警告: カンマ式の左側のオペランドは効果がありません。

  [-Wunused-value]   i = (i, ++i, 1) + 1;
                        ^

なぜ?しかし、おそらくそれは、私の最初の質問の答えによって自動的に答えられるでしょう。

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

式中 (i, ++i, 1) のように、使用されるカンマは カンマ演算子

<ブロッククオート

カンマ演算子(トークンで表される , は二項演算子で、最初のオペランドを評価してその結果を破棄し、次に二番目のオペランドを評価してその値 (と型) を返します。)

最初のオペランドを破棄するため、一般的に 最初のオペランドが望ましい副作用を持つ場合にのみ有効です。 . 最初のオペランドに対する副作用が発生しない場合、コンパイラは効果がない式であることを警告することがあります。

つまり、上の式では、左端の i が評価され、その値は破棄されます。すると ++i が評価され i の値は1だけ増加し、再び式 ++i は破棄されます。 に対する副作用はありません。 i は永続的 . 次に 1 が評価され、式の値は次のようになります。 1 .

と等価である。

i;          // Evaluate i and discard its value. This has no effect.
++i;        // Evaluate i and increment it by 1 and discard the value of expression ++i
i = 1 + 1;  

注意点 上記の式は完全に有効であり、未定義の動作を呼び出すものではありません。 というのは シーケンスポイント カンマ演算子の左オペランドと右オペランドの評価の間にあります。