前缀加一、减一操作符在C/C++中的不同语义问题

来源:互联网 发布:德众网络工程有限公司 编辑:程序博客网 时间:2024/05/04 21:05
$ 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两行语句在不同环境下编译时得到的不同结果。

0 0
原创粉丝点击