以下のコードは、C コンパイラでのコンパイルでエラーが発生します
++(-i);
error: lvalue required as increment operand
-i が右辺値を返すことを意味します。
ながらコード
++(+i);
エラーを出さないでください。なんでそうなの?このリンクは、 +i が左辺値にならないことを示しています。
これはコンパイラの不具合です。C 言語では、演算子が適用される前であっても、式のすべての左辺値が右辺値に変換されます。ただし、sizeof
、&
、++
、--
および代入の左辺のオペランドは例外です.
(6.3.2/2 を参照) 。
言い換えれば、C 言語で+i
は、単項+
が右辺値を生成すると思われるからではなく、その単項がその機能を実行する機会を得る前i
に右辺値に変換されるため、右辺値を生成する必要があります。+
たとえば、int i
値を保持する変数の場合42
、式+i
は式と完全に同等+42
です。の左辺値性i
は失われ、単項のセマンティクスが作用する42
前+
に変換されます。
言うまでもなく、この場合、unary の結果が+
左辺値になる可能性はありません。
C99 標準から ( 6.5.3.3 単項算術演算子):
2 単項 + 演算子の結果は、その (プロモートされた) オペランドの値です。オペランドに対して整数昇格が実行され、結果は昇格された型になります。
3 単項 - 演算子の結果は、その (プロモートされた) オペランドの否定です。オペランドに対して整数昇格が実行され、結果は昇格された型になります。
この特定のコンテキストでは、昇格された値を使用するコードはありません+i
。したがって、コンパイラはそれが と同等であると想定しi
、このため、それを左辺値として扱うと思います。または、単項+
をまったく実装していないだけかもしれません。とにかく、それはあなたがすべきことではありません.他のコンパイラは単にそれを禁止します.
-i
実際の操作を実行するため、その結果は一時的なものです。したがって、それはもう変数ではないため、インクリメントすることはできません。
そして、標準は6.3.2.1 その他のオペランド / Lvalues、arrays、および function designators でそれを明確にします:
2 sizeof 演算子、単項 & 演算子、++ 演算子、--演算子、または . の左オペランドの場合を除きます。演算子または代入演算子の場合、配列型を持たない左辺値は、指定されたオブジェクトに格納されている値に変換されます (左辺値ではなくなります)。[…]