Possible Duplicate:
square of a number being defined using #define
Can you please explain why the following code outputs "29"?
#define Square(x) (x*(x))
void main()
{
int x = 5;
printf("%d", Square(x+3));
}
Possible Duplicate:
square of a number being defined using #define
Can you please explain why the following code outputs "29"?
#define Square(x) (x*(x))
void main()
{
int x = 5;
printf("%d", Square(x+3));
}
Since macros only do textual replacement you end up with:
x + 3 * (x + 3)
which is 29.
You should absolutely always put macro arguments between parentheses.
#define Square(x) ((x)*(x))
Better yet, use a function and trust the compiler to inline it.
EDIT
As leemes notes, the fact that the macro evaluates x
twice can be a problem. Using a function or more complicated mechanisms such as gcc statement expressions can solve this. Here's a clumsy attempt:
#define Square(x) ({ \
typeof(x) y = (x); \
y*y; \
})
Please note that although the macro
#define Square(x) ((x)*(x))
seems to solve the problem, it does not. Consider this:
int x = 5;
printf("%d\n", Square(x++));
The preprocessor expands this to:
((x++)*(x++))
which is undefined behavior. Some compilers will evaluate this as
(5 * 5)
which seems as expected in the first place. But x = 7
afterwards, since the increment operator has been applied twice. Clearly not what you were looking for.
For the output, see here: http://ideone.com/9xwyaP
(*Macros which tend to be used as a replacement for inline-functions.)
You can fix this in C++ using template functions which can handle all types and in C by specifying a concrete type (since even overloading isn't supported in C, the best you can get is different functions with suffixes):
// C
int SquareI(int x) { return x * x; }
float SquareF(float x) { return x * x; }
double SquareD(double x) { return x * x; }
// C++
template<typename T>
T Square(T x) { return x * x; }
Specifically for GCC, there is another solution, since GCC provides the typeof
operator so we can introduce a temporary value within the macro:
#define Square(x) ({ typeof (x) _x = (x); _x * _x; })
Et voila: http://ideone.com/OGu08W
Operator precedence. You see, because Square is a macro, not a function, this is what the compiler actually sees:
(x+3*(x+3))
Which operator precedence ends up as:
5 + (3 * (8))
Or 29. To fix the problem:
#define Square(x) ((x)*(x))
The preprocessor replaced Square(x) with x*(x).
Your code looks like printf("%d", x+3*(x))
.
You should use #define Square(x) ((x)*(x))
.