0

I am currently learning C++ and I like to read and explore programs I find on the internet.

I have found this example C++ code, which gives "4 is greater than 2" as an output, but I cannot figure out why:

#include <stdio.h>
#define MAX( a, b ) ( a > b ) ? (a) : (b)

int main()
{
    int x = 2, y = 2;

    if( MAX( ++x, y ) == x )
    {
        printf( " %d is greater than %d ", x, y );
    }

    return 0;
}

What I do not understand is: if you look at the segment which states

if( MAX( ++x, y ) == x )

it is supposed to increase the X variable by 1, then call MAX; at that point X should be 3. Instead, when you compile it the output is as aforementioned.

I have done some research on how the ++ operator works ( Incrementing in C++ ) but I could not get the solution anyway. Could you please explain me why this happens?

Thanks in advance for your help.

Community
  • 1
  • 1
Flora
  • 299
  • 3
  • 11
  • http://coliru.stacked-crooked.com/a/d7074b79ca3dd7ca – chris Jan 19 '14 at 01:23
  • http://stackoverflow.com/questions/319452/are-all-macros-evil - If I were you I would stay away from macros in c++ as much as I can. Its better to use templates and inlines for that. – Gasim Jan 19 '14 at 01:56

1 Answers1

4

The preprocessor expands your condition to

if( ( ++x > y ) ? (++x) : ((y) == x))

This increments x twice - ++x > y is equivalent to 3>2 so the condition evaluates true, resulting in ++x being evaluated again.

Also, as Benjamin Lindley points out, you need extra parentheses around the macro if you want it to return the maximum of two values in this case:

#define MAX( a, b ) (( a > b ) ? (a) : (b))
simonc
  • 41,632
  • 12
  • 85
  • 103
  • Actually, the expansion is `if( (++x > y) ? (++x) : (y) == x )`, which is a completely different expression since `==` has higher precedence than `?:`. – Benjamin Lindley Jan 19 '14 at 01:29
  • @BenjaminLindley Thanks, I've corrected my answer and added a note about this. – simonc Jan 19 '14 at 01:36
  • 1
    I think the extra parantheses would lead to undefined behaviour in this special case, since there is no sequence point between `++x` (*after* `?`) and `x` (after `==`). – mb84 Jan 19 '14 at 01:46
  • 2
    This is why `std::max()` and its friends all [explicitly note that the parameters are evaluated once and only once](http://stackoverflow.com/questions/3665574/only-one-evaluation-guaranteed-for-stdmin-stdmax). – Aaron D. Marasco Jan 19 '14 at 01:49
  • Thank you very much guys, it makes sense now; I did not think about the "#define" behaviour. – Flora Jan 19 '14 at 01:54
  • @mb84: Yep. Also note that if you change `MAX` to a proper function, such as `std::max`, it is again undefined behavior. – Benjamin Lindley Jan 19 '14 at 02:01