I tried to play with the definition of the macro SQR
in the following code:
#define SQR(x) (x*x)
int main()
{
int a, b=3;
a = SQR(b+5); // Ideally should be replaced with (3+5*5+3), though not sure.
printf("%d\n",a);
return 0;
}
It prints 23
. If I change the macro definition to SQR(x) ((x)*(x))
then the output is as expected, 64
. I know that a call to a macro in C replaces the call with the definition of the macro, but I still can’t understand, how it calculated 23
.
The macro and its parameters should be enclosed in parentheses. When macro parameters or expression are not parenthesized, the intended logic may get disrupted after expanding the macro.
In C, the macro is used to define any constant value or any variable with its value in the entire program that will be replaced by this macro name, where macro contains the set of code that will be called when the macro name is used in the program.
The double-number-sign or token-pasting operator (##), which is sometimes called the merging or combining operator, is used in both object-like and function-like macros. It permits separate tokens to be joined into a single token, and therefore, can't be the first or last token in the macro definition.
Macro substitution is a mechanism that provides a string substitution. It can be achieved through "#deifne". It is used to replace the first part with the second part of the macro definition, before the execution of the program. The first object may be a function type or an object.
Pre-processor macros perform text-replacement before the code is compiled so
SQR(b+5)
translates to
(b+5*b+5) = (6b+5) = 6*3+5 = 23
Regular function calls would calculate the value of the parameter (b+3) before passing it to the function, but since a macro is pre-compiled replacement, the algebraic order of operations becomes very important.
Consider the macro replacement using this macro:
#define SQR(x) (x*x)
Using b+5
as the argument. Do the replacement yourself. In your code, SQR(b+5)
will become: (b+5*b+5)
, or (3+5*3+5)
. Now remember your operator precedence rules: *
before +
. So this is evaluated as: (3+15+5)
, or 23
.
The second version of the macro:
#define SQR(x) ((x) * (x))
Is correct, because you're using the parens to sheild your macro arguments from the effects of operator precedence.
This page explaining operator preference for C has a nice chart. Here's the relevant section of the C11 reference document.
The thing to remember here is that you should get in the habit of always shielding any arguments in your macros, using parens.
Because (3+5*3+5 == 23)
.
Whereas ((3+5)*(3+5)) == 64
.
The best way to do this is not to use a macro:
inline int SQR(int x) { return x*x; }
Or simply write x*x
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With