Unexpected output printf statement

96 views Asked by At

Why outputs of i and j in the following two printf()s are different?

#include <cstdio>
#define MAX(x,y) (x)>(y)?(x):(y)
int main()
{
    int i=10,j=5,k=0;
    k==MAX(i++,++j);
    printf("%d %d %d\n",i,j,k);
    i=10,j=5,k=0;
    k=MAX(i++,++j);
    printf("%d %d %d\n",i,j,k);
    return 0;
}

I think only k should differ, but it is showing different output for all, i, j and k, in printf() statement. What is the reason?

Output :

11 7 0
12 6 11
5

There are 5 answers

0
Mohit Jain On BEST ANSWER

k==MAX(i++,++j); is translated to:

  k==(i++) > (++j) ? (i++) : (++j);
/* 2       1       3  : Precedance */

In your case i = 10 and j = 5, so the comparision would be 10 v/s 6 which would be true or 1 with side effect i becomes 11 and j becomes 6. (Recall that: Macros are not functions)

As k = 0 and not equal to 1, k==(i++) > (++j) would be false and ++j would be executed. Causing j to be incremented to 7.

In latter case, there is no modification to the value of variables.

When can I expect same output in both case? Even if you change the macro with a function, your arguments have the side effects, which would cause the output 11 6 for i j, so you are changing the variables using ++ operator, don't expect both statements to have the same values.

0
Sourav Ghosh On
  • Let's analyse the output from first printf()

    1. Assuming you meant = instead of == in your code,

      k==MAX(i++,++j);
      

      gets translated to

       k = (i++) > (++j) ? (i++): (++j)
      

      which gets evaluated changing all the values of i, j and k.

    2. Even if you meant ==, as mentioned in the answer by Mr. Mohit Jain, you'll face similar issue with precedence.

    Have a look at operator precedence for better understanding.

  • Let's analyse the output from second printf()

In the second printf() statement, you're re-setting the values of i, j, k and not using the MACRO. So, those values will get printed. Simple.

So, TL;DR, before first printf(), the MACRO changes all the three values for i, j, k. So, your output for first and second printf() differs for all the three variable values.


FWIW, if you meant the MACRO to behave as a ternary conditional expression , you need to change your MACRO definition to

#define MAX(x,y) ( (x)>(y) ? (x) : (y) )

To avoid issues with operator precedence after MACRO expansion.

2
ouah On

You have side-effects.

MAX(i++,++j)

is expanded to

(i++)>(j++)?(i++):(j++)

And i is modified twice in the macro call.

Moreover, you have to add parens to your macro definition:

#define MAX(x,y) ((x)>(y)?(x):(y))
0
Simon On

i++ and ++j both increment i and j, so you change their values before printing.

0
Weather Vane On

The macro is a red herring. OP did not ask about k but "Why output of i and j in following two printf are different?" The answer is because i and j have been modified between setting their values and printing, in the first case, but not in the second case.