3

我正在寻找以下代码片段中的 L1 和 L2 行如何不同 wrt 的解释l-values,即,为什么我C2105 error在 L1 中得到:,但在 L2 中没有?

*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,前缀增量/减量返回一个左值。因此,执行后增量时没有错误。来自前缀增量/减量的 C++ 文档:

结果是与操作数类型相同的左值。

看L1,它变成:

++( ( *s )++ )

...在操作数优先级之后。根据定义,后增量运算符评估表达式(返回 r 值),然后对其进行变异。来自后增量/减量的 C++ 文档:

结果的类型与后缀表达式的类型相同,但不再是左值。

...并且您不能对 r 值进行前缀递增/递减,因此会出错。

参考:

于 2013-08-15T18:13:25.977 回答