前缀加一、减一操作符在C/C++中的不同语义问题
2006-02-23 10:22
295 查看
$ 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两行语句在不同环境下编译时得到的不同结果。
相关文章推荐
- 前缀加一、减一操作符在C/C++中的不同语义问题
- android 保存具有不同前缀的同一号码分别为A和B,用其中一个呼叫,通话记录一直显示另一个联系人名字的问题
- c++不同的命名空间访问的问题
- c++中箭头操作符(->)和点操作符(.)有什么不同
- 【面试常见问题】【C++】指针和引用的区别,有哪些不同点,细细道1
- C++ 01 类与对象 值语义与对象语义问题
- c++中不同场景构造函数的次序问题:
- c++中箭头操作符(->)和点操作符(.)有什么不同
- C++命名空间中操作符函数的动态链接问题
- 改善C++ 程序的150个建议学习之建议12:优先使用前缀操作符
- android 保存具有不同前缀的同一号码分别为A和B,用其中一个呼叫,通话记录一直显示另一个联系人名字的问题
- C++初始化列表问题,类中有一个对象类型的数组成员变量,在初始化列表中初始化时报错“[]”操作符语法错误
- C++重载输入和输出操作符以及IO标准库中的刷新输入缓冲区残留字符问题
- 【面试常见问题】【C++】指针和引用的区别,有哪些不同点,细细道2
- C++技术问题总结-第13篇 调用约定有哪些,有什么不同
- android 保存具有不同前缀的同一号码分别为A和B,用其中一个呼叫,通话记录一直显示另一个联系人名字的问题
- 跨平台C++软件开发中,由于不同操作系统对Unicode的支持差异,而导致的一些问题及解决方案
- More Effective C++之Item M6:自增(increment)、自减(decrement)操作符前缀形式与后缀形式的区别
- C++重载输入和输出操作符以及IO标准库中的刷新输入缓冲区残留字符问题
- C++、Java和Matlab不同语言关于 y=(++x)+(++x);结果不同的问题