This is what the compiler sees after the pre-processor has done it's evil thing.
Code:
$ gcc -E foo.c | tail
int main()
{
printf("%d ", (4)*(4));
int x = 3;
printf("%d ", (++x)*(++x));
return 0;
}
This is what the compiler thinks about it.
Code:
$ gcc -Wall foo.c
foo.c: In function ‘main’:
foo.c:10:26: warning: operation on ‘x’ may be undefined [-Wsequence-point]
10 | printf("%d ", SQUARE(++x)); // Expecting 16 but getting 25
| ^
foo.c:3:20: note: in definition of macro ‘SQUARE’
3 | #define SQUARE(x) (x)*(x)
| ^
The problem is, your macro expansion ends up doing ++x twice, so you're surprised by the result.