后置增量 i++ 何时执行?被处决?

发布于 2024-10-26 04:42:47 字数 1136 浏览 1 评论 0原文

可能的重复:
未定义的行为和序列点

在机器代码级别的 C++ 中,后自增 ++ 运算符何时执行被处决?

优先级表表明 postfix++ 运算符是级别 2:这意味着在

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

The postfix ++ 中首先执行

然而,这行代码的逻辑运算似乎是先进行加法(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++ 生成的代码被插入到加法操作的下方

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

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

Possible Duplicate:
Undefined Behavior and Sequence Points

In C++ on a machine code level, when does the postincrement++ operator get executed?

The precedence table indicates that postfix++ operators are level 2: which means in

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

The postfix ++'s execute first.

However, it would seem that the logical operation of this line is the addition happens first (0+0), but how does that happen?

What I imagine, is the following:

// 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.

So, the other option is although x++ is higher on the precedence table that x + x, the code generated due to x++ is inserted below the addition operation

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

That second option seems to make more sense, but I'm interested in the order of operations here. Specifically, when does x change?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

我ぃ本無心為│何有愛 2024-11-02 04:42:47

我不会直接讨论 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之前执行,或者x先于y):

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
...

Instead of jumping on the details of the example that is UB, I will discuss the following example that is perfectly fine:

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

Now, the precedence of operators means that the last line is equivalent to:

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

And not:

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

On the other hand, the semantics of the post increment are equivalent to two separate instructions (from here on is just a mental picture):

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

That is, the original expression will be interpreted by the compiler as:

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

But the compiler is allowed to reorder the 5 instructions as long as the following constraints are met (where x>y means x must be executed before y, or x precedes y):

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

There are no other constraints in the order of execution of the different instructions, so the following are all valid sequences:

1, 2, 3, 4, 5
1, 2, 5, 3, 4
1, 3, 2, 4, 5
...
野鹿林 2024-11-02 04:42:47

int y = x++ + x++ ;

是未定义的行为。任何事情都可能发生,包括一些不合理的结果、程序崩溃或其他任何情况。只是不要那样做。

This

int y = x++ + x++ ;

is undefined behavior. Anything can happen, including some unreasonable results, program crashing or whatever else. Just don't do that.

并安 2024-11-02 04:42:47

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

考虑以下情况:

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

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

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

In C++ there are things called "sequence points". If you alter a value more than once without an intervening sequence point, the behaviour is undefined.

Consider the following:

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

The value of y could be 0, 1 or some other completely random value.

Bottom line is, don't do it. Nothing good can come of it. :-)

冬天旳寂寞 2024-11-02 04:42:47

在您的情况下,当您使用 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

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

In your case, is seems like the following happens

When you use x++, x increments after the operation is complete.

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

While

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

However, different compilers will handle it differently and your application might crash if you increment twice in the same statement.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文