Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Behaviour and Order of evaluation in C# [duplicate]

Possible Duplicate:
C#: Order of function evaluation (vs C)

Code snippet:

i += ++i;
a[++i] = i;
int result =  fun() - gun();
//statement of similar kind

Are their behavior well-defined in C#? In C++, such code invokes undefined/unspecified behavior. Please also quote the relevant sections from the language specification in your response!

like image 565
Nawaz Avatar asked Nov 29 '22 17:11

Nawaz


2 Answers

The key here is the table in "1.4 Expressions", and "7.3.1 Operator precedence and associativity". I won't duplicate the table from 1.4, but to quote 7.3.1:

  • Except for the assignment operators, all binary operators are left-associative, meaning that operations are performed from left to right. For example, x + y + z is evaluated as (x + y) + z.
  • The assignment operators and the conditional operator (?:) are right-associative, meaning that operations are performed from right to left. For example, x = y = z is evaluated as x = (y = z).

The first is logically expanded (or: use the associativity rules) as:

i = i + ++i;

here, the order (from the table) is pre-increment, then additive, then assignment - so we should expect i to double plus one. And indeed, with i=6, we get 13 as expected.

a[++i] = i;

again from the table, order should be array access, pre-increment, assignment - so I would expect the i+1'th value to be i+1. And indeed, checking:

    int[] a = { 0, 0, 0, 0, 0 };
    int i = 2;
    a[++i] = i;

we do indeed get {0, 0, 0, 3, 0}.

With the last, method invocation takes priority over subtraction, then it is left-to-right; so it should be fun(), gun(), -, assignment.

like image 177
Marc Gravell Avatar answered Dec 02 '22 06:12

Marc Gravell


People always get this so confused, which is unfortunate because in C# it is extremely straightforward. The rules are:

  • subexpressions are observed to be evaluated left to right when observed from the executing thread, period, end of story. (Order of evaluation is permitted to be observed to be different by some other thread if some other thread is watching the side effects.)

  • the order in which the operators execute is determined by their precedence and associativity.

Those are the only two relevant rules, and they completely define the behaviour of the code you give. In

i += ++i; 

first i is evaluated, then ++i is evaluated, and then the += is executed.

a[++i] = i; 

First 'a' is evaluated, then ++i is evaluated, then the indexing operator runs, then i is evaluated, then the assignment happens.

int result =  fun() - gun(); 

first result is evaluated, then fun, then gun, then the subtraction, then the assignment.

Please also quote the relevant sections from the language specification in your response!

You are perfectly capable of looking in the table of contents. It's not hard to find.

like image 22
Eric Lippert Avatar answered Dec 02 '22 05:12

Eric Lippert