The tricky part here is not the order of operations, but the way that macros are expanded. It's easy to make these sort of mistakes even when you know what is going on.
1 2 3 4
#define MAX(x, y) x > y ? x : y // bad
#define MAX(x, y) (x > y ? x : y) // less bad
#define MAX(x, y) ((x) > (y) ? (x) : (y)) // better, but still not good if x and y have
// side-effects or are expensive to evaluate
Unless you have to for the aforementioned course, I would avoid using function-like macro and almost all other macros as well (except for ones needed for #includes, and other versioning/OS stuff).
It's a C relic that really just doesn't belong in C++. Just use const variables, and functions.
FurryGuy: Not even close. A macro is just a source text replacement. If a macro is written with a certain kind of parameter in mind and the user passes a different kind, all that will happen is that the program will fail to compile, or at worst will be incorrect.
1 2 3 4 5 6 7 8 9
#define APPEND_FIVE(s) ((s) += '5')
//...
std::string s;
APPEND_FIVE(s);
int n = 0;
APPEND_FIVE(n);
std::function<void()> f;
APPEND_FIVE(f);