postincrement i ++什么时候执行?

时间:2011-03-25 14:33:41

标签: c++ post-increment

  

可能重复:
  Undefined Behavior and Sequence Points

在机器代码级别的C ++中,postincrement ++运算符何时执行?

precedence table表示postfix ++运算符为2级:这意味着在

int x = 0 ;
int y = x++ + x++ ;  // ans: y=0

后缀++的执行首先

但是,这条线的逻辑运算似乎是首先添加(0 + 0),但是这是怎么回事?

我的想法如下:

// Option 1:
// Perform x++ 2 times.
// Each time you do x++, you change the value of x..
// but you "return" the old value of x there?
int y = 0 + x++ ;  // x becomes 1, 0 is "returned" from x++

// do it for the second one..
int y = 0 + 0 ;  // x becomes 2, 0 is "returned" from x++... but how?
// if this is really what happens, the x was already 1 right now.

所以,另一种选择是虽然x + x在x + x的优先级表上更高,但由于x ++而生成的代码插入以下添加操作

// Option 2:  turn this into
int y = x + x ; // 
x++ ;
x++ ;

第二种选择似乎更有意义,但我对这里的操作顺序很感兴趣。具体来说, x何时更改

4 个答案:

答案 0 :(得分:7)

int y = x++ + x++ ;

is undefined behavior. Anything can happen,包括一些不合理的结果,程序崩溃或其他任何事情。只是不要这样做。

答案 1 :(得分:7)

我不会跳过UB示例的详细信息,而是讨论以下非常好的示例:

int a = 0, b = 0;
int c = a++ + b++;

现在,运算符的优先级意味着最后一行等同于:

int c = (a++) + (b++);

而不是:

int c = (a++ + b)++; // compile time error, post increment an rvalue

另一方面,后增量的语义相当于两个单独的指令(从这里开始只是一个心理图片):

a++; // similar to: (__tmp = a, ++a, __tmp) 
     // -- ignoring the added sequence points of , here

也就是说,原始表达式将被编译器解释为:

auto __tmp1 = a;         // 1
auto __tmp2 = b;         // 2
++a;                     // 3
++b;                     // 4
int c = __tmp1 + __tmp2; // 5

但只要满足以下约束条件,就允许编译器重新排序5条指令(其中x>y表示必须在x之前执行y,或xy)之前:

1 > 3        // cannot increment a before getting the old value
2 > 4        // cannot increment b before getting the old value
1 > 5, 2 > 5 // the sum cannot happen before both temporaries are created

执行不同指令的顺序没有其他限制,因此以下是所有有效序列:

1, 2, 3, 4, 5
1, 2, 5, 3, 4
1, 3, 2, 4, 5
...

答案 2 :(得分:4)

在C ++中有一些名为“sequence points”的东西。如果您在没有插入序列点的情况下多次更改某个值,则行为未定义

请考虑以下事项:

int x = 0;
int y = x++ + x++;

y的值可以是0,1或其他一些完全随机的值。

底线是,不要这样做。什么都没有好处。 : - )

答案 3 :(得分:2)

在您的情况下,似乎发生以下情况

当您使用x++时,x在操作完成后递增。

int y = x++ + x++ ;
// First add 0+0
// Increment x
// Increment 

虽然

int y = ++x + ++x ;
// Add (increment x) and (increment x) = 1+1 = 2

但是,不同的编译器会以不同的方式处理它,如果在同一语句中增加两次,应用程序可能会崩溃。