int main()
{
int i=3;
(++i)++;
printf("%d",i);
}
このプログラムは g++ コンパイラで動作しますが、gcc では動作しません。i++++ または ++i++ と書くと、cpp でも機能しません。c-expression と c++-expression には違いがあると思います。L値とR値について誰か説明してくれませんか?
int main()
{
int i=3;
(++i)++;
printf("%d",i);
}
このプログラムは g++ コンパイラで動作しますが、gcc では動作しません。i++++ または ++i++ と書くと、cpp でも機能しません。c-expression と c++-expression には違いがあると思います。L値とR値について誰か説明してくれませんか?
編集:この回答は、更新された質問には正しくありません。最初に述べた質問に適用されます。
(i++)++
両方の言語でファイルをCまたはC++として解析しているかどうかに関係なく、gccまたはg ++のいずれでも機能しないはずです。postfixインクリメントでは、オペランドとして左辺値が必要であり、結果は右辺値になります。
(右辺値はC ++で正式にのみ使用されることに注意してください。Cでは、式の結果は明示的に左辺値であるか、単に左辺値ではありません。右辺値という用語は、C標準の標準テキストではまったく使用されていません。)
簡単に言うと、左辺値はオブジェクト、つまり概念的にはどこかにあるストレージの領域を参照する式です。変更可能な左辺値は、代入が有効なものであるため、代入式の左側に表示できます。
右辺値は単なる値であり、変更可能な左辺値を割り当てることができますが、割り当てることはできません。代入式の右側にのみ表示できます。
g++
エラーが発生します:lvalue required as increment operand
。
プレフィックスのインクリメント(およびデクリメント)はわずかに異なります。C ++では、プレフィックスの増分の結果は明示的に左辺値(5.3.2 / 1 [expr.pre.incr])になります。Cでは、明示的に左辺値ではありません(6.5.3.1は、++ Eが(E + = 1)と同等であると述べています。6.5.16は、割り当ての結果が左辺値ではないことを示しています)。
(++i)++
したがって、C ++でのみ意味的に正しいですが、シーケンスポイントを介さずにオブジェクトに値を2回格納しているため、動作は未定義です。
ウィキから:
一部の言語では、左辺値と右辺値の概念を使用しています。左辺値は、実行中のプログラムにプログラムでアクセスできるアドレスを持つ値です(たとえば、C ++の「&」などの演算子のアドレスを介して)。つまり、変数または特定のメモリ位置への逆参照参照です。右辺値は、左辺値(以下を参照)または非左辺値(左辺値と区別するためにのみ使用される用語)にすることができます。Cでは、左辺値という用語は元々、代入できるものを意味していました(左値から来て、代入演算子の左側にあることを示します)が、言語に「const」が追加されたため、これは現在、 「変更可能な左辺値」。
5.2.6ドル
後置++を適用して得られる値は、演算子を適用する前にオペランドが持っていた値です。[注:取得された値は元の値のコピーです]オペランドは変更可能な左辺値でなければなりません。オペランドの型は、算術型または完全なオブジェクト型へのポインタでなければなりません。結果が記録された後、オブジェクトがbool型である場合を除き、オブジェクトの値は1を加算することによって変更されます。ただし、bool型の場合はtrueに設定されます。[注:この使用は非推奨です。付録Dを参照してください。]結果は右辺値です。結果のタイプは、オペランドのタイプのcv非修飾バージョンです。5.7および5.17も参照してください。
$ 5.3.2 /1-
「プレフィックス++のオペランドは、1を加算して変更するか、boolの場合はtrueに設定します(この使用は非推奨です)。オペランドは変更可能な左辺値でなければなりません。」
これで、C++で発生するエラーを説明できるはずです。