Jul 4, 2014

C Programming #36: Parameterised Macro

We are already dealt with the basics of Macro here. Macros just are not used for representation of constant but also can accept parameters like function (but in very limited way).

 Syntax:

#define X(a,b,c) expression_using_a_b_c

Here macro X takes here parameter a,b and c and replaces it in with expression that contains a, b, c.

Example: Macro to find Square of a number



#include <stdio.h>
#define SQR(x) x*x
int main()
{
   int s;

   s = SQR(5);
   printf("Square of 5 is %d\n", s);

   s = SQR(2+3);
   printf("Square of 2+3 is %d\n", s);

   return 0;
}

Output is


Square of 5 is 25
Square of 2+3 is 11

Oh something went wrong, home come square value of 2+3 is 11. Lets see this case in detail.
What would the macro of SQR(2+3) get replaced to statement s = SQR(2+3) would become s = 2+3*2+3. Multiplication has more precedence than addition. (read this article for more details). Which will evaluate to s = 2+6+3; which will finally make the value of s as 11.

How do solve the problem ? We need to do addition before multiplication in above case, this can be done by putting brackets around it. s = (2+3)*(2+3) would have yielded correct value 25.


Change in macro should be as follows



#include <stdio.h>
#define SQR(x) (x)*(x)
int main()
{
   int s;

   s = SQR(5);
   printf("Square of 5 is %d\n", s);

   s = SQR(2+3);
   printf("Square of 2+3 is %d\n", s);

   return 0;
}

Output is


Square of 5 is 25
Square of 2+3 is 25

Say we had similar macro say

#define ADD(x,y) (x)+(y)

But say we did 

x = ADD(1,2) * ADD(2,3);

We are expecting 3*5 i.e 15.
Lets expand the macro and see

x = (1)+(2)*(2)+(3) => x = (1) + (4) + (3) = 8.

Oh snap, again we got wrong value. This can be solved by putting one pair of brases.

#define ADD(x,y) ((x) +(y))

Hence perfect macro of square would be 

#define SQR(x) ((x)*(x))

Note that parameterised macro is not function call. Comparison of parameterized macro and function call


  1. Function call would involve creation of stack while in pameterised macro stack is not invoked.
  2.  Hence macros would be faster. (No need to create and destroy stack, more info in next article)
  3. There is not type checking in paremeterized macro. Hence the same SQR could be used to find sqaure of float also.
  4. Which is good as well as bad. Typechecking will reduce lot of potential bugs during compilation time itself.

This completed the pre-processing as a whole. For review here are the all the articles that cover on pre-processor
  1. C Programming #29: Constant Macros
  2. C Programming #34: Journey from source code to executable
  3. C Programming #35: Preprocessor
  4. C Programming #36: Parameterized Macro

Links

Previous Article - C Programming #35: Preprocessor
All Article - C Programming

No comments :

Post a Comment