$ cat -n 1.c
1 int main( int argc, char **argv )
2 {
3 int i = 0;
4 /*++i = 3;*/
5 ++(++i);
6 ++(i++);
7 (++i)++;
8 (i++)++;
9 }
$ cat 1.c | gcc -x c -ansi -
<stdin>: In function `main':
<stdin>:5: error: invalid lvalue in increment
<stdin>:6: error: invalid lvalue in increment
<stdin>:7: error: invalid lvalue in increment
<stdin>:8: error: invalid lvalue in increment
$ cat 1.c | gcc -x c++ -ansi -
<stdin>: In function `int main(int, char**)':
<stdin>:6: error: non-lvalue in increment
<stdin>:8: error: non-lvalue in increment
$
上面这段代码被分别作为 C 和 C++ 两种代码进行编译,得到了不同的错误提示。当作为 C 代码进行编译时,第5到第8行代码全部出错。而作为 C++ 代码编译时,只有 6、8两行代码被提示错误。这里揭示了一个事实:C和C++代码在一定程度上,区别已经不能再被忽视了。
对于prefix ++/-- 操作符,C++ 标准在 5.3.2 节 Unary expression -> Increment and decrement 中进行了详细的解释。对于 prefix ++/-- 操作符来说,必须满足如下条件:
1、操作数是数学类型或指向经过完整定义的类型对象的指针。后者确定了对指针进行 ++/-- 时实际跳过的字节数。
2、如果操作数类型为bool,则操作数被设为true;否则,操作数被递增1。表达式的值就是新的操作数的值。
3、prefix 表达式的结果是 lvalue。
最关键的就是上面的第三点,因为 C 和 C++ 在另外两点中语义基本差别不大,但是在第三点中具有显著的差别。C++98 中规定,赋值操作符、自反赋值和前缀递增操作符的结果是 lvalue,而 C99 中将赋值操作符的结果设定为非 lvalue,因此导致了第5、7两行语句在不同环境下编译时得到的不同结果。