How does C # evaluate expressions that contain assignments?

I had a C / C ++ background. I came across a weird way of exchanging two values ​​in C #.

int n1 = 10, n2=20;
n2 = n1 + (n1=n2)*0;

In C #, the above two lines change the values ​​between n1and n2. For me this is unexpected, as in C / C ++, the result should be n1=n2=20.

So how does C # evaluate an expression ? It seems that the +above is considered as function callingfor me. The following explanation seems appropriate. BUT it seems to me like me.

  • The first is executed (n1=n2). And so n1=20.
  • Then, n1in the n1+ (n1=n2)*0not yet 20. It is processed as a function of the parameter, so put on the stack and remains 10. Therefore, n2=10+0=10.
+4
source share
3 answers

In C #, sub-expressions are evaluated in order from left to right, with side effects produced in that order. This is defined in section 7.3 of the C # 5 specification:

The operands in the expression evaluate from left to right.

It is important to understand that the procedure for evaluating sublicense is independent of priority (aka order of operations) and associativity. For example, in a type expression A() + B() * C(). The order of evaluation in C # always A(), B(), C(). My limited understanding of C / C ++ is that this order is a detail of the compiler implementation.

n1 (10) +. (n1=n2). n2 (20), n1. n1 20. 20 * 0, 0. 10 + 0 (10) n2. , n1 = 20 n2 = 10.

.

+4

, , , IL.

IL_0000:  ldc.i4.s    0A 
IL_0002:  stloc.0     // n1
IL_0003:  ldc.i4.s    14 
IL_0005:  stloc.1     // n2

ldc.i4 (int 4) , stloc. *

IL_0006:  ldloc.0     // n1
IL_0007:  ldloc.1     // n2
IL_0008:  stloc.0     // n1
IL_0009:  stloc.1     // n2

, . , n1 n2, , n1 n2 ( )

, , .NET.

mikez , , 7.3.1

, :

  • , -, , . , x + y + z (x + y) + z.

  • , (?:) -, , . , x = y = z x = (y = z). . , x + y * z y z, x, (x + y) * z x y, z.

, , , , ,

n2 = (n1) + ((n1=n2)*0)

(n1) + (..) , .

+4

, :

7.5.1.2 Estimating the execution time of argument lists

Argument list expressions are always evaluated in the order they are written. So an example

class Test
{
  static void F(int x, int y = -1, int z = -2) {
      System.Console.WriteLine("x = {0}, y = {1}, z = {2}", x, y, z);
  }
  static void Main() {
      int i = 0;
      F(i++, i++, i++);
      F(z: i++, x: i++);
  }
}

outputs a conclusion

x = 0, y = 1, z = 2
x = 4, y = -1, z = 3

You can see that this also applies to arithmetic operations if you change your code to:

int n1 = 10, n2=20;
n2 = (n1=n2) * 0 + n1;

Now both n1and n2are equal 20.

+2
source

All Articles