Can the following macro bring problems?
#define sq(x) x*x
If yes, then how and why?please help.
For one, operator precedence would be messed up:
sq(2+2); // author wants 4*4, but gets 2+2*2+2.
I'm not going to give you a straight answer (this looks like a homework question), but I'm going to give you an example that will hopefully make you think about it and come up with a correct answer:
#include <iostream>
#define sq_macro(x) x * x
int sq_function(int x)
{
return x * x;
}
int print_and_ret(int x)
{
std::cout << x << '\n';
return x;
}
int main()
{
std::cout << "Calling sq_macro:\n";
sq_macro(print_and_ret(10));
std::cout << "Calling sq_function:\n";
sq_function(print_and_ret(10));
}
When you run the program, the macro and the function give two different behaviors. Think about what a macro is, and what a function is.
All of these can cause trouble:
int x = 12;
int n = sq(x+3);
int y = sq(x++);
int z = 2 * sq(2 + n) * n;
comparared with a function sq
.
As pointed out, you should wrap each use of the argument in parentheses to ensure correct behavior, for example, when the argument is something like i * 2
:
#define sq(x) ((x)*(x))
But there is another potential issue. Consider the following:
result = sq(++i);
This is translated to:
result = ((++i)*(++i))
Where as the intention was likely to increment i
only once, it gets incremented twice. This is a common side effect for macros.
One approach is just to be aware of this when calling it, but a better one is to put sq()
in its own inline function.
While writing macros use brackets excessively. Rewrite the macro as follows
#define sq(x) ((x)*(x))
If you don't do this then you will have problems in cases where macro is used as sq(5+4)
To understand the problem do macro expansion and see.
Yes, it can present problems. Other than the obvious fact that macros don't respect namespaces at all (which means you can't call anything else sq
), try the following:
int result = sq(4) / sq(4);
You should surround x * x
with parenthesis so it becomes ((x) * (x))
.
Another problem:
int a = 0;
int result = sq(++a);
This is an inherent problem with macros, and is one reason inline functions should be preferred.