后增量运算符:意外行为

发布于 2024-09-10 09:25:04 字数 1254 浏览 5 评论 0原文

可能的重复:
谁能解释一下这些未定义的行为(i = i++ + ++i , i = i++ 等...)

我的代码如下:

#include <stdio.h>
int main()
{
  int x = 10, y = 0;
  x = x++;
  printf("x: %d\n", x);
  y = x++;
  printf("y: %d\n", y);
}

鉴于后增量的性质,我期望以下输出:

x: 10
y: 10

我的推理是在第 5 行中,应分配 x增量发生后恢复到其初始值。

然而,相反,我得到了这样的信息:

x: 11
y: 11

深入研究程序集,这对我来说似乎是一个故意的选择:

LCFI2:
        movl    $10, -4(%rbp)   // this is x
        movl    $0, -8(%rbp)    // this is y
        incl    -4(%rbp)        // x is simply incremented
        movl    -4(%rbp), %esi
        leaq    LC0(%rip), %rdi
        movl    $0, %eax
        call    _printf
        movl    -4(%rbp), %eax  // now x is saved in a register,
        movl    %eax, -8(%rbp)  // copied to y,
        incl    -4(%rbp)        // and finally incremented
        movl    -8(%rbp), %esi
        leaq    LC1(%rip), %rdi
        movl    $0, %eax
        call    _printf

这里发生了什么? GCC 是想把我从自己的困境中拯救出来吗?我没有方便的语言参考,但我认为这破坏了预期的语义。

Possible Duplicate:
Could anyone explain these undefined behaviors (i = i++ + ++i , i = i++, etc…)

My code is as follows:

#include <stdio.h>
int main()
{
  int x = 10, y = 0;
  x = x++;
  printf("x: %d\n", x);
  y = x++;
  printf("y: %d\n", y);
}

Given the nature of post-increment, I would expect the following output:

x: 10
y: 10

My reasoning is that in line 5, x should be assigned to its initial value after the increment takes place.

Instead, however, I get this:

x: 11
y: 11

Digging into the assembly, this looks like a deliberate choice to me:

LCFI2:
        movl    $10, -4(%rbp)   // this is x
        movl    $0, -8(%rbp)    // this is y
        incl    -4(%rbp)        // x is simply incremented
        movl    -4(%rbp), %esi
        leaq    LC0(%rip), %rdi
        movl    $0, %eax
        call    _printf
        movl    -4(%rbp), %eax  // now x is saved in a register,
        movl    %eax, -8(%rbp)  // copied to y,
        incl    -4(%rbp)        // and finally incremented
        movl    -8(%rbp), %esi
        leaq    LC1(%rip), %rdi
        movl    $0, %eax
        call    _printf

What's going on here? Is GCC trying to save me from myself? I don't have a language reference handy but I would have thought that this breaks the intended semantics.

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

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

发布评论

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

评论(4

葬﹪忆之殇 2024-09-17 09:25:04

该行为未定义,因为 x = x++ 中没有中间序列点,请参见 C 常见问题

The behaviour is undefined as there is no intervening sequence point in x = x++, see e.g. the C FAQ.

人海汹涌 2024-09-17 09:25:04

C 语言未定义后置/预置/递减何时发生。因此,诸如 x = x++ 之类的语句格式不正确 - 请避免使用它们。

It is left undefined by the C language as to when exactly a post/pre-in/decrement occurs. Thus, statements such as x = x++ are not well formed - avoid them.

亽野灬性zι浪 2024-09-17 09:25:04

撇开标准不谈(因为这对于标准来说是未定义的),它的运行方式正是我所期望的。

我的经验法则是,对于包含 x++ 的行,将 x++ 替换为 x 并输入 x += 1 > 在以下行(或预增量的前一行)。

遵循该经验法则,您的代码将写为

#include <stdio.h>
int main()
{
  int x = 10, y = 0;
  x = x; // x: 10
  x += 1; // x: 11
  printf("x: %d\n", x);
  y = x; // y: 11
  x += 1; // x: 12
  printf("y: %d\n", y);
}

Standards aside (since this is undefined with respect to the standard), the way it ran is the way I would have expected it.

My rule of thumb is that for a line with x++, you substitute x++ with x and put x += 1 on the following line (or preceding line for pre-increment).

Following that rule of thumb, your code would be written as

#include <stdio.h>
int main()
{
  int x = 10, y = 0;
  x = x; // x: 10
  x += 1; // x: 11
  printf("x: %d\n", x);
  y = x; // y: 11
  x += 1; // x: 12
  printf("y: %d\n", y);
}
讽刺将军 2024-09-17 09:25:04

当你:

a = b++;

发生的事情是 b 被保存到 a 中,并且在分配完成后 b 增加 1。所以如果你这样做:

x = x ++;

并且之前 x 是 10 ,将会发生的情况是 10 将被保存到 x 中,并且之后(在 printf 完成之前)x 将增加 1 到 11。这就是打印 11 的原因。

When you have:

a = b++;

what is happening is that b is saved to a and after the assigment is done b is incremented by one. So if you do:

x = x ++;

and previously x was 10 what will happen is 10 will be saved to x and after(before your printf is done) x is incremented by one to 11. That's why 11 is printed.

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