私は自分のgccでこれを試しました:
int a=1;
cout<<(--a)--;
出力は0です。しかし、それをに変更します
cout<<--(a--);
エラーが発生します(デクリメントオペランドとして左辺値が必要です)。誰かがこれについて私に教えてもらえますか?
ありがとう!
の両方のバージョンは++
引数として左辺値を必要としますが、接頭辞バージョンは引数として左辺値を返し、後置バージョンは右辺値を返します。
いずれにせよ、シーケンスポイント間で同じオブジェクトを2回変更することはできないため、「動作する」例ではundefind動作が呼び出されます。出力は、コンパイラーが実行したいと思うものであれば何でもかまいません。好奇心から質問しているだけなら問題ありませんが、これが実際のコードに関連している場合は、何か間違ったことをしている可能性があります。
predecrementは--a
デクリメントa
し、それからあなた自身を返しa
ます。したがって、後置デクリメントを含め、任意の方法で変更を続けることができます。
postdecrementはa--
デクリメントa
しますが、デクリメント前のaの値を返します。それは本質的にあなたにのコピーを与えていますa
。ただし、このコピーを事前にデクリメントすることはできません。これは左辺値ではないため、デクリメントするものはありません。それがエラーである理由です。
プレデクリメントはへの参照を返すものと考え、ポストデクリメントはa
定数値で返すものと考えてください。
(--a)--
シーケンスポイントを介在させずに同じオブジェクトを2回変更するため、これは未定義の動作です。コンパイラは、UBを呼び出したときにレポートする必要はありません。多くの状況で、UBを検出することさえできません。ただし、適切な警告をオンにすると(そして、自分の警告が何を提供するかを確認する必要があります)、場合によってはそれが可能になることがあります。
--(a--)
プレフィックスデクリメントには左辺値が必要ですが、ポストフィックスデクリメントは右辺値を返します。これは、未定義の動作とは異なり、コンパイラが報告する必要があるエラーです。