1

Please explain working in each case.

Why both cases have same output?

Case I:

int main (void)
{
    int i = 5;
    if(i == ++i)           //plz explain here How values are checked
       printf("Equal");
    else
      printf("Not Equal");

  return 0;
}
//Output: Equal;

Case II:

int main (void)
{
    int i = 5;
    if(++i == i)            //plz explain here How values are checked
       printf("Equal");
    else
      printf("Not Equal");

  return 0;
}
//Output: Equal;
Javed Akram
  • 15,024
  • 26
  • 81
  • 118

2 Answers2

10

Neither of those programs is valid; you are not allowed to read and update the same variable without a sequence point in between. Thus, it is undefined behavior what either of those programs will do, and so the fact that they may happen to return the same answer on your compiler and machine doesn't mean anything.

Jeremiah Willcock
  • 30,161
  • 7
  • 76
  • 78
  • 7
    @Javed Akram: Yes -- one possible result of undefined behavior is that the code appears to work normally, and may even produce the results you expect. Then again, it might not do either one. The most common result, of course, is that it seems to work fine in testing, and then does something horrible when you demo it for client. – Jerry Coffin Mar 14 '11 at 04:22
  • @Jerry well, i dont think the machine code will fluctuate just because of demoing, but try switch compiler (even a simple upgrade might do the trick) and see when you will start to cry. – stefan Mar 14 '11 at 04:24
  • @Jerry @Jeremiah, so please explain where is the undefined behavior in these two programs – Javed Akram Mar 14 '11 at 04:26
  • @stefan: The machine code itself may not change, but the circumstances under which it runs can and will change enough to cause problems. – Jerry Coffin Mar 14 '11 at 04:26
  • 1
    @Javed Akram: C99, §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." The old C standard had a similar requirement though its paragraph number was different. – Jerry Coffin Mar 14 '11 at 04:30
  • Note that with `gcc` version 4.4.4, compiling either one with the `-Wall` flag will result in an *Undefined Behavior* warning – SiegeX Mar 14 '11 at 06:12
0

It is equal because this is C. As the other answer says, the result of this operation is undefined because you violate C rules -- which means that you cannot guarantee the same answer when switching compilers (although all compilers may be implemented similar, which doesn't make it a guarantee). The fact that C allows you to shoot yourself in the foot does not mean that it is good practice to do so.

Now, why does it work?

Conjecture #1:

i may be stored in a register, say r1, and the compiler may be compiling this entire comparison into one single CMP instruction, with an autoincrement addressing mode. Say it is CMP ++r1, r1 or CMP r1, ++r1, then depending on the actual CPU, both may return a true compare.

Conjecture #2:

The compiler may be compiling the compare into:

inc r1   // increment r1
CMP r1, r1   // compare with itself

Conjecture #3:

The compiler may be optimizing to always put a simple variable access to the right hand side. It is allowed to do that because the order of execution in a == operator is undefined and the compiler can rearrange things as it likes.

Stephen Chung
  • 14,497
  • 1
  • 35
  • 48