4

Please consider the following statement:

int a[]={1,2,3,4,5,6,7,8};
int i=0,n;
n=a[++i] + i++ + a[i++] + a[i] ;

According to my logic n should be 10. But I am getting different output in c (output is 7) However in java I am getting expected result that is 10. Is there any difference in the way in which increment and decrement operators work in c and java.

Here is my exact c and java code:

         #include <stdio.h>
            int main()
            {
                int a[]={1,2,3,4,5,6,7,8};
                int i=0,n;
                n=a[++i] + i++ + a[i++] + a[i] ;
                printf("%d",n);
                getch();
                return 0;
            }

Java code with output : 10

public class HelloWorld{

     public static void main(String []args){

        int a[]={1,2,3,4,5,6,7,8};
        int i=0,n;
        i=0;
        n=a[++i] + i++ + a[i++] + a[i] ;
        System.out.println(n);
     }
}
Abhas Tandon
  • 1,859
  • 16
  • 26
  • 3
    The Java designers chose to precisely define the results for all cases of increment etc., although the JLS recommends avoiding multiple side effects in one statement. The C++ standards leave some cases undefined. – Patricia Shanahan Jul 16 '13 at 19:11
  • You mean that the reason why the result is 7 and not 10 is so called 'undefined behavior of c' Actually answer can be 7 if you evaluate the expression from right to left instead of left to right. Are you sure it has nothing to do with operator associativity. – Abhas Tandon Jul 16 '13 at 19:15
  • 3
    It's intriguing that everyone comes up with the same question. More so that they all bump into *undefined behavior*. Maybe C should be called *undefined language*. – devnull Jul 16 '13 at 19:16
  • Who in their right mind would ever write such code? – duffymo Jul 16 '13 at 19:23
  • I'm surprised that OP didn't ask a[i++] = i++ doesn't give expected results. – devnull Jul 16 '13 at 19:26
  • _Maybe C should be called undefined language._ As a C programmer who's been doing Java for 20 years, I agree! Perhaps that's why newer languages go to such extreme lengths to define this behavior. – PaulProgrammer Jul 16 '13 at 19:29
  • see [this](http://programmingclassroom.com/tips/cAndcplusplus/CandCplusplusTip0002.pdf) article – Anirudha Jul 16 '13 at 19:29
  • 1
    To be a little more blunt than @duffymo -- Do not write code this way. I certainly hope this question just came up out of curiosity and nothing that you were actually doing in practice. – Ryan Jul 16 '13 at 19:32
  • It results in Undefined behavior See [here](http://stackoverflow.com/questions/17473706/understanding-sequence-point-in-c) is a good explanation for this. – haccks Jul 16 '13 at 19:39
  • @devnull A lot of these choices in C and C++ were made to allow the compiler freedom to optimize better. Honestly, do you really want to support code that modifies the same variable multiple times in one expression? It is just bad style and should be discouraged even if the language supports it. – Shafik Yaghmour Jul 16 '13 at 20:11

3 Answers3

3

In C, that's an undefined behaviour. Since C doesn't guarantee the order of evaluation of individual operation in an expression.

Rohit Jain
  • 209,639
  • 45
  • 409
  • 525
  • Actually answer can be 7 if you evaluate the expression from right to left instead of left to right. Are you sure it has nothing to do with operator associativity. – Abhas Tandon Jul 16 '13 at 19:20
  • Is there anything that I need to remember in particular about order of evaluation of expression in c (where can I found some well defined rules if there are any?) – Abhas Tandon Jul 16 '13 at 19:21
  • 4
    @AbhasTandon. You can't. That is why it's called undefined behaviour. In general, you should avoid modifying the same variable more than once in the same expression. – Rohit Jain Jul 16 '13 at 19:25
  • *undefined behavior* seems to be the new *Hello World*. – devnull Jul 16 '13 at 19:30
3

With respect to C from the c99 draft standard 6.5.2:

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.

it cites the following code examples as being undefined:

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

The section is same in the draft 2011 standard as well but it reads a bit more awkward. This is a good reference on sequence point.

Section 15.7 is the relevant section from the JLS:

The Java programming language guarantees that the operands of operators appear to be evaluated in a specific evaluation order, namely, from left to right.

It is recommended that code not rely crucially on this specification. Code is usually clearer when each expression contains at most one side effect

Community
  • 1
  • 1
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
2

To add to Rohit's answer, if you do each of the steps separately, the answer 10 is given. This just highlights that the execution of i++ and ++i may not be happening in the order the arguments are being added to the value n.

#include <stdio.h>
int main()
{
    int a[]={1,2,3,4,5,6,7,8};
    int i=0,n;
    n=a[++i] + i++ + a[i++] + a[i] ;
    printf("%d\n",n);

    i=0;
    n=0;
    n=a[++i];
    printf("%d\n",n);
    n+=i++;
    printf("%d\n",n);
    n+=a[i++];
    printf("%d\n",n);
    n+=a[i];
    printf("%d\n",n);
    return 0;
}
PaulProgrammer
  • 16,175
  • 4
  • 39
  • 56