【问题标题】:Why do both ++i and i++ generate temporaries为什么 ++i 和 i++ 都生成临时文件
【发布时间】:2014-05-26 23:14:51
【问题描述】:

我记得在某处读到过,对于变量int i,++i 和 i++ 都会在 C# 中生成一个临时变量。有谁知道为什么会这样?它们的性能是否相同?

更新

所以从 Eric Lippert 在副本中的回答来看,预增量的步骤如下:

对于预增量

1) x 被评估以产生变量

2) 变量的值被复制到一个临时位置

3) 临时值递增以产生新值(不会覆盖临时值!)

4) 新值存储在变量中

5) 运算结果为新值

为什么需要第 2 步?为什么不就地增加变量呢?

【问题讨论】:

  • 我猜他们是一样的。
  • ++i 不应该创建临时文件。你从哪里得到这些信息的?
  • @Fedor,Eric Lippert 在他对副本的回答中这么说。
  • 它创建临时,eric explains it here
  • @Ned,我相信 Eric 会解释它:x could be volatile and changing on another thread; the value returned by x++ is not the current value of x, it is what x was assigned, and that could be different。在 preincrement 的情况下,同样的原则也适用(变量可能是 volatile 或者另一个线程可能正在改变它)。

标签: c#


【解决方案1】:

答案是:他们没有。不是标题所暗示的意思。

首先请注意:根据 Eric 的文章(令人惊讶的是,该文章受到了许多人的批评),在 C# 中发生在前增量和后增量中的事件顺序是相同的。不仅相似,而且相同。同样的事情以同样的顺序发生。

其次,没有“临时工”本身。 Eric 所指的“临时位置”是概念性的,但实际上对应于机器寄存器。一个值从内存复制到寄存器,值递增,然后将值存回内存。

但还有另一个方面。与 C/C++ 不同,C# 保证表达式的求值顺序。在 C# 中,以下代码是明确定义的,而在 C 中则不是。

j = ++i + i++;

但是采取更简单的方法:

j = ++i + f(i); // first
j = i++ + f(i); // second

在第一种情况下,变量的值可用于后续表达式,但在第二种情况下则不行。相反,在以下函数调用中使用的第一个增量会产生一个概念上的临时性。在第二种情况下可以使用一个额外的寄存器。

【讨论】:

    猜你喜欢
    • 2022-07-13
    • 1970-01-01
    • 1970-01-01
    • 2012-08-25
    • 2023-03-17
    • 1970-01-01
    • 1970-01-01
    • 2017-10-23
    • 2011-10-06
    相关资源
    最近更新 更多