1

I get 12 and 49 from this code

#include <stdio.h>
#define product(a) a*a

int main() {
    int i = 3, j, k;
    j = product(i++);
    k = product(++i);
    printf("%d %d\n", j, k);

    return 0;
}

If instead of using macro you use a function then you get 9 and 25, which is what I would expect...

Can someone explain why does this happen?

Patricio Sard
  • 2,092
  • 3
  • 22
  • 52
  • The code is basically using a macro to partially conceal the undefined behaviour that the duplicate question shows more explicitly. The issue is the same: dual increments of `i` between sequence points lead to undefined behaviour. – Jonathan Leffler Jun 11 '16 at 05:49
  • @JonathanLeffler Actually I knew from before that using more than one of those operators in the same sentence produce undefined behavior, the problem I had was that I didn't know what was the macro doing... – Patricio Sard Jun 11 '16 at 06:31

2 Answers2

1

If you expand the macro, the line

j = product(i++);

becomes

j = i++*i++;

and the line

k = product(++i);

becomes

k = ++i*++i;

Both these lines are subject to undefined behavior. You can try to make sense of it for one run of the program but the results are not guaranteed to be same with a different compiler or even the same compiler with different compiler flags.

When you use a function call instead of a macro, the behavior of the code is more straight forward. The line

j = product(i++);

is equivalent to:

int temp = i;
j = product(temp);
i++;

The line

k = product(++i);

is equivalent to:

++i;
k = product(i);

Hence, there are no problems when a function is used instead of a macro.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
0

The output you expect will require you to change the macro to a function

#include <stdio.h>
int product(int a) { return a * a; }

int main() {
    int i = 3, j, k;
    j = product(i++);
    k = product(++i);
    printf("%d %d\n", j, k);

    return 0;
}

Output

9 25

Since macro unpacks inline, the value of i changes in the main function's callframe and you get an unexpected result.

Shreevardhan
  • 12,233
  • 3
  • 36
  • 50