pre/post-increment 运算符在变量分配之前的行为如何?

How does the pre/post-increment operator behave before variable allocation?

int x=3, y=4, n=0;
int n = x * y / --x;

此代码计算出 n 为 6,但我认为是 4;因为 --x 是预递减运算符并且优先级高于 */ 所以它将是 2 * 4 / 2 我假设它是 2*4 而不是 3*4 因为 x 已经递减了,所以我在这里缺少什么?同样的问题已被问到 但答案是 PHP 特定的。

如果我们编译此代码然后使用 ildasm 检查它,我们将得到以下指令(使用 https://en.wikipedia.org/wiki/List_of_CIL_instructions 翻译):

 IL_0000:  nop          // I compiled in debug mode, this does nothing
 IL_0001:  ldc.i4.3     // Push 3 onto the stack as int32.  
 IL_0002:  stloc.0      // Pop a value from stack into local variable 0.
 IL_0003:  ldc.i4.4     // Push 4 onto the stack as int32.  
 IL_0004:  stloc.1      // Pop a value from stack into local variable 1.
 IL_0005:  ldloc.0      // Load local variable 0 onto stack.
 IL_0006:  ldloc.1      // Load local variable 1 onto stack.
 IL_0007:  mul          // Multiply values.
 IL_0008:  ldloc.0      // Load local variable 0 onto stack.
 IL_0009:  ldc.i4.1     // Push 1 onto the stack as int32.  
 IL_000a:  sub          // Subtract value2 from value1, returning a new value.
 IL_000b:  dup          // Duplicate the value on the top of the stack.
 IL_000c:  stloc.0      // Pop a value from stack into local variable 0.    
 IL_000d:  div          // Divide two values to return a quotient or floating-point result. 
 IL_000e:  stloc.2      // Pop a value from stack into local variable 2.
 IL_000f:  ret          // Return from method, possibly with a value.   

这表明表达式是从左到右求值的,即使 --x*/ 之前。

这也记录在 C# 语言规范中(第 7.3 节运算符):

The order of evaluation of operators in an expression is determined by the precedence and associativity of the operators (§7.3.1).

Operands in an expression are evaluated from left to right. For example, in F(i) + G(i++) * H(i), method F is called using the old value of i, then method G is called with the old value of i, and, finally, method H is called with the new value of i. This is separate from and unrelated to operator precedence.