编译器如何解释前递增/递减和后递增/递减

时间:2011-06-29 22:38:13

标签: c++ return-value postfix-operator prefix-operator

当有人询问后递增/递减和预递增/递减之间的区别时,响应通常是前缀版本向变量添加一个并返回变量的新值,而后缀版本添加一个变量并返回旧值。

虽然搞乱了,但我发现所有这些都是合法的:

int i = 1;
++i;
++++++++++++++i;
(++++++++++++++i)++;
(++++++(++++(++i)))++;
------i;
--++++--++----++i;
i+=++++++++++++++i+i++-i--; 

但以下所有行都不合法:

i++++;
++i++;
--i--;

如果我假设前缀版本通过引用返回,这一切都有意义(即使是最后一个示例,因为postfix的优先级高于前缀)。

假设/实现前缀版本是否返回引用,后缀版本是否返回正确的值?对于前/后加/减运算符,我还有其他微妙的行为差异吗?

4 个答案:

答案 0 :(得分:2)

  

这一切都是合法的:

不,这不合法。以这种方式多次编写变量是Undefined Behavior。它在语法上是正确的,它会编译,但肯定是不合法的。

答案 1 :(得分:1)

在C ++中,前缀增量/减量表达式“返回”左值,后缀版本返回rvalues。在C中,两种形式都返回rvalues。

但是,请注意,如果尝试在两个序列点之间多次写入变量,则行为未定义。所以这种区别无论如何都不重要。

答案 2 :(得分:0)

想到的是在同一语句中至少使用两次变量的常见编码错误,至少有一个实例应用前/后增量:

i = i++;

答案 3 :(得分:0)

  

是假设/实现的   前缀版本返回引用和   后缀版本返回一个值   正确

没有。你为什么这么认为?它是一个内置的运算符,编译器可以按照自己的意愿实现它。

您的“合法”示例可能会编译,但会产生未定义的行为,因为您在没有序列点的情况下多次读取和写入同一个变量。