3

l-values以下のコード スニペットの行 L1 と L2 が wrtでどのように異なるかについての説明を探していC2105 errorます。

*s = 'a';
printf("%c\n", *s );
//printf("%c\n", ++(*s)++ ); //L1 //error C2105: '++' needs l-value
printf("%c\n", (++(*s))++);  //L2
printf("%c\n", (*s) );

注: コードを .cpp ファイルとしてコンパイルすると、上記の結果が得られました。ここで、.c ファイルとしてコンパイルすると、L1 と L2 の両方の行で同じエラー C2105 が発生します。L2 が C++ でコンパイルされ、C ではコンパイルされない理由は、別の謎です :(.

参考になれば、私は Visual C++ Express Edition を使用しています。

4

2 に答える 2

4

Compiler see ++(*s)++ as ++((*s)++), as post-increment has higher precedence than pre-increment. After post-incrementation, (*s)++ becomes an r-value and it can't be further pre-incremented (here).
And yes it is not a case of UB (at least in C).
And also read this answer.

For L2 in C++ not giving error because
C++11: 5.3.2 Increment and decrement says:

The operand of prefix ++ is modified by adding 1, or set to true if it is bool (this use is deprecated). The operand shall be a modifiable lvalue. The type of the operand shall be an arithmetic type or a pointer to a completely-defined object type. The result is the updated operand; it is an lvalue, and it is a bit-field if the operand is a bit-field. If x is not of type bool, the expression ++x is equivalent to x+=1.

C++11:5.2.6 Increment and decrement says:

The value of a postfix ++ expression is the value of its operand. [ Note: the value obtained is a copy of the original value —end note ] The operand shall be a modifiable lvalue. The type of the operand shall be an arithmetic type or a pointer to a complete object type. The value of the operand object is modified by adding 1 to it, unless the object is of type bool, in which case it is set to true. The value computation of the ++ expression is sequenced before the modification of the operand object. With respect to an indeterminately-sequenced function call, the operation of postfix ++ is a single evaluation. [ Note: Therefore, a function call shall not intervene between the lvalue-to-rvalue conversion and the side effect associated with any single postfix ++ operator. —end note ] The result is a prvalue. The type of the result is the cv-unqualified version of the type of the operand.

and also on MSDN site it is stated that:

The operands to postfix increment and postfix decrement operators must be modifiable (not const) l-values of arithmetic or pointer type. The type of the result is the same as that of the postfix-expression, but it is no longer an l-value.

于 2013-08-15T18:06:23.717 に答える
1

完全性と C++ ドキュメントからの引用:

L2 を見ると、prefix-increment/decrement は左辺値を返します。したがって、ポストインクリメントを実行してもエラーは発生しません。prefix-increment/decrement の C++ ドキュメントから:

結果は、オペランドと同じ型の左辺値です。

L1 を見ると、次のようになります。

++( ( *s )++ )

...オペランドの優先順位の後。定義による後置インクリメント演算子は、式を評価し (右辺値を返す)、それを変更します。ポスト インクリメント/デクリメントの C++ ドキュメントから:

結果の型は後置式の型と同じですが、左辺値ではなくなりました。

...そして、r値をプレフィックスインクリメント/デクリメントできないため、エラーになります。

参考文献:

于 2013-08-15T18:13:25.977 に答える