1

I know the below code will lead to undefined behaviour according to c/c++ standard but what about in c#? ,After some searching I found that in c# all the arguments/variables in an expression are evaluated from left to right(please correct me if am wrong), If this is true than the result(output of res variable) of below program should be 3, but its 4 ??.

class Program
{
    static void Main(string[] args)
    {
        int a = 1;
        int res = (a++) + (++a); //Will This Lead to Undefined Behavior(Like in C/C++)..??
        Console.WriteLine(res);
        Console.ReadLine();
    }
}

The result is fine for these expressions when checked with left to right evaluation.

res = a + ++a; \\Successfully evaluates res to 3

res = ++a + a; \\Sussessfully evaluates res to 4

res = ++a + a++; \\Successfully evaluates res to 4

Similarly

res= a++ + ++a ;\\should be 3, why i get it 4 ??

Can Anybody explain am confused.??

usr
  • 168,620
  • 35
  • 240
  • 369
Mysterious Jack
  • 621
  • 6
  • 18
  • 4
    Why you think that `res= a++ + ++a` should be 3? – Hamlet Hakobyan Nov 02 '14 at 11:52
  • You might also find http://stackoverflow.com/q/1860615/11683 interesting. – GSerg Nov 02 '14 at 11:55
  • 2
    I don't even see why you expected 3. I'm calculating this in my mind and I'm getting 4. Anyway, defined behavior is not about what you expect - it's about what's required to happen for the sake of consistency. If this expression evaluates to `whatever`, it's guaranteed to evaluate to `whatever` in every compliant implementation (regardless of how "obvious" the value `whatever` is as the value of the expression). – Theodoros Chatzigiannakis Nov 02 '14 at 11:56
  • am incrementing the value of a++ after evaluating the complete expression.??? I was calculating like this:- i) temp0=a (evaluating a++, just substituting 1,But Not incrementing it) ii) temp1=++a (First Incrementing 1 and then substituting it) iii) res=temp0+temp1 iv) a=a+1 (evaluating a++,as expression has reached semicolon, now incrementing to 1) – Mysterious Jack Nov 03 '14 at 01:47

5 Answers5

5

Your program is equivalent to:

var a = 1;
var temp0 = a++;
var temp1 = ++a;
var res = temp0 + temp1;

And the result of that is 4.

Even simpler:

var a = 1;
var temp0 = a; a++;
a++; var temp1 = a;
var res = temp0 + temp1;

C# does not have Undefined Behavior like C/C++. That would undermine the security properties of .NET. That said .NET can and does have implementation defined behavior in a few places. Not here, though.

usr
  • 168,620
  • 35
  • 240
  • 369
  • Ok. Its making sense now, But shouldn't the value of a++ should be incremented after evaluating the complete expression.???, I was calculating like this:- i) temp0=a (evaluating a++, just substituting 1,But Not incrementing it) ii) temp1=++a (First Incrementing 1 and then substituting it) iii) res=temp0+temp1 iv) a=a+1 (evaluating a++,as expression has reached semicolon, now incrementing to 1) – Mysterious Jack Nov 03 '14 at 01:43
  • The increment operation is an expression that is evaluated locally like any other expression. It's side-effects are not "queued" to the end of the statement. – usr Nov 03 '14 at 09:41
  • Thanks @usr but I have read it in C text book, it clearly says increment the post increment variable after evaluating the expression, does this mean that in c and c# its evaluation different?? – Mysterious Jack Nov 04 '14 at 11:31
  • Expression and statement are two different things. The post-increment operator applies its side-effect after the expression has been evaluated. – usr Nov 04 '14 at 11:58
  • Expression is nothing but a combination of operators and operands ended by semicolon. So when You say expression we should not count complete statement(complete expression ended by semicolon)..??, but Only a operand..?? – Mysterious Jack Nov 05 '14 at 07:28
  • In any given statement there can be (and usually are) many nested expressions. The a++ evaluation performs its side-effect after the expression a has been evaluated. It does not care about the rest of the statement. – usr Nov 05 '14 at 09:17
  • @MudassirHussain A statements (usually) ends with a semicolon, not an expression. `x + 1`, `y = x + 1`, etc. are expressions. `y = x + 1;` is a statement. – Tavian Barnes Nov 08 '14 at 19:37
3

a++ == 1 (now, a = 2), then ++a == 3

1 + 3 = 4

Seems right to me.

Simon Broadhead
  • 3,483
  • 21
  • 19
2

The difference between var b = a++ and var b = ++a is the time that the variable a gets changed.

  • b = a++ first assigns the value of a to variable b and then increases a.
  • b = ++a first increases the value of a and then assigns it to variable b.

The time of the assignment makes the difference. So here is your code annotated:

int a = 1;     // a = 1
int res = 
    a++        // the value of a (1 is inserted into the equation) and a is increased by 1 - so a == 2
    + ++a      // a is increased by one (a == 3) and its value is inserted into the equation
    ;          // (res = (1 + 3)) == 4

To make it clearer, the code could be rewritten as follows. And actually this is how the C# stack evaluates your code:

int a = 1;
int res = 0;
res += a;      // add a to res                                                - a == 1, res = 1
a += 1;        // increase a (could also be written as a++ or ++a);           - a == 2, res = 1
a += 1;        // increase a again (could also be written as a++ or ++a);     - a == 3, res = 1
res += a;      // add a to res                                                - a == 3, res = 4

In the equation a's value is used and not it's reference. So each time the variable a occurs in the equation its current value gets pushed to the stack and is then used in the subsequent evaluation of the equation.

AxelEckenberger
  • 16,628
  • 3
  • 48
  • 70
1

start condition a=1, res=0

res = a++ => res = 1, a = 2

+ ++a => a=3 BEFORE addition, res = 4, result is correct

davidc
  • 132
  • 1
  • 4
0

I agree with Volte and davidc. Just try use two variables instead of one (a). For example:

int a = 1;
int b = 1;
Console.WriteLine("{0}", a++ + ++b); //this write 3 on console
Console.ReadLine();

This proves that our threory is true.