-3

in C

#include <stdio.h>  
int main(){  
  int x=100;  
  x=x++ + x++;  
  printf("x :  %d\n",x); // prints 202  
  return 0;
}

in Java

class Demo{ 
  public static void main(String args[]){  
    int x=100; 
    x=x++ +  x++;  
    System.out.printf("x : %d",x); // prints 201  
  }
}

why these two languages prints different values?what happens 'x=x++ + x++;' line ?

pixylife
  • 463
  • 4
  • 12
  • 2
    Why on Earth is everything on one line, even in edit? – chris May 19 '13 at 19:36
  • If you don't edit,people will miss the point. It's probably not that bad a question, although pretty commonly asked here. – zw324 May 19 '13 at 19:36
  • 7
    It's undefined behaviour in C. It could be 42 in C, or format your hard drive. – Daniel Fischer May 19 '13 at 19:36
  • Just to make people feel better, it's basically of duplicate of this anyway: http://stackoverflow.com/questions/949433/could-anyone-explain-these-undefined-behaviors-i-i-i-i-i-etc – chris May 19 '13 at 19:38
  • Why this include is HUGE? – Maroun May 19 '13 at 19:40
  • 1
    @MarounMaroun, That's what happens to stuff beginning with # when it's not indented and thus, code. – chris May 19 '13 at 19:41
  • 1
    @MarounMaroun Wasn't indented, so interpreted as markdown. `#` means big header in markdown. – Daniel Fischer May 19 '13 at 19:41
  • 3
    @luzifer In Java, `x++ + x++` is evaluated left to right, `x = x++ + x++;` is equivalent in effect to `left = x++; right = x++; x = left + right;`, so `left` will be 100, and `x` incremented to 101, then `right` is set to 101, `x` incremented to 102. Then `x` is set to `left + right = 100 + 101`. In C, as said, undefined behaviour, `x` is modified more than once without intervening sequence point. – Daniel Fischer May 19 '13 at 20:02
  • 1
    The short version of the comment by @DanielFischer is: "because they're different languages and treat things differently." – Nik Bougalis May 19 '13 at 20:45

1 Answers1

2

Java and C are different languages, so not all constructs that are syntactically valid in both (there are many, since Java's syntax builds on C's) must have the same meaning in both.

The construct

int x=100; 
x=x++ +  x++;

is an example. In Java, the evaluation order of an expression is specified as left-to-right, and the side-effect of incrementing x in x++ must have taken place before the next part of the expression is evaluated. Hence the above code is - except for the temporary variables - equivalent to

int x = 100;
int left = x++;   // sets left to x's value (100) and increments x, so x is now 101
int right = x++;  // sets right to x's current value (101) and increments x, so x is now 102
x = left + right; // 100 + 101 = 201

in Java.

In C, the order of evaluation of the subexpressions composing an expression is not specified, and further, the side-effect of incrementing x in x++ can take place at any time after the previous sequence point and the next sequence point.

Therefore it is undefined behaviour in C to modify the same object more than once without intervening sequence point (old parlance), in the 1999 version of the C language standard, that was expressed (in paragraph 2 of section 6.5) as

Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be read only to determine the value to be stored.70)

70) This paragraph renders undefined statement expressions such as

   i = ++i + 1;
    a[i++] = i;
while allowing
    i = i + 1;
    a[i] = i;

The current (2011) version of the standard exchanged the "sequence point" terminology with "sequenced before/after" and "unsequenced", paragraph 2 of section 6.5 now reads

If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined. If there are multiple allowable orderings of the subexpressions of an expression, the behavior is undefined if such an unsequenced side effect occurs in any of the orderings.84)

(footnote 84 is the previous footnote 70).

The two side effects of incrementing the scalar object x in x = x++ + x++, and the side effect of storing the computed value of the right hand side in the scalar object x are unsequenced, hence the behaviour is undefined.

The compiler may reject to compile a programme containing an expression x++ + x++ or completely ignore the undefined behaviour (or anything in between). If it compiles the programme successfully, every runtime behaviour of the line

x = x++ + x++;

is equally valid. The standard imposes no restrictions on the behaviour.

Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431