Sometimes while programming, we stumble upon a condition where we want to use a value or a small piece of code many times in a code. Also there is a possibility that the in future, the piece of code or value would change. Then changing the value all over the code does not make any sense. There has to be a way out through which one can make the change at one place and it would get reflected at all the places. This is where the concept of a macro fits in.
A Macro is typically an abbreviated name given to a piece of code or a value. Macros can also be defined without any value or piece of code but in that case they are used only for testing purpose.
Lets understand the concept of macros using some example codes.
Defining Macros without values
The most basic use of macros is to define them without values and use them as testing conditions. As an example, lets look at the following piece of code :
#include <stdio.h> #define MACRO1 #define MACRO2 int main(void) { #ifdef MACRO1 // test whether MACRO1 is defined... printf("\nMACRO1 Defined\n"); #endif #ifdef MACRO2 // test whether MACRO2 is defined... printf("\nMACRO2 Defined\n"); #endif return 0; }
- So, the above code just defines two macros MACRO1 and MACRO2.
- As clear from the definition, the macros are without any values
- Inside the main function, the macros are used only in testing conditions.
Now, if we look at the output, we will see :
$ ./macro MACRO1 Defined MACRO2 Defined
Since both of the macros are defined so both the printf statements executed.
Now, one would question where are these testing macros used. Well, mostly these type of testing macros are used in a big project involving many source and header files. In such big projects, to avoid including a single header more than once (directly and indirectly through another header file) a macro is defined in the original header and this macro is tested before including the header anywhere so as to be sure that if the macros is already defined then there is no need to include the header as it has already been included (directly or indirectly).
Defining Macros through command line
Another use of testing macros is where we want to enable debugging (or any other feature) in a code while compilation. In this case, a macro can be defined through compilation statement from command line. This definition of macro is reflected inside the code and accordingly the code is compiled.
As an example, I modified the code used in example of the last section in this way :
#include <stdio.h> #define MACRO1 int main(void) { #ifdef MACRO1 // test whether MACRO1 is defined... printf("\nMACRO1 Defined\n"); #endif #ifdef MACRO2 // test whether MACRO2 is defined... printf("\nMACRO2 Defined\n"); #endif return 0; }
- So now only MACRO1 is defined
- While MACRO2 is also being used under a condition.
If the above program is now compiled and run, we can see the following output :
$ ./macro MACRO1 Defined
So we see that since only MACRO1 is defined so condition related to MACRO1 executed. Now, if we want to enable or define MACRO2 also then either we can do it from within the code (as shown in first example) or we can define it through the command line. The command for compilation of the code in that case becomes :
$ gcc -Wall -DMACRO2 macro.c -o macro
and now if we run the code, the output is :
$ ./macro MACRO1 Defined MACRO2 Defined
So we see that MACRO2 got defined and hence the printf under the MACRO2 condition got executed.
Macros with values
As discussed in the introduction, there are macros that have some values associated with them. For example :
#define MACRO1 25
So, in the above example, we defined a macro MACRO1 which has value 25. The concept is that in the preprocessing stage of the compilation process, the name of this macro is replaced with macros value all over the code. For example :
#include <stdio.h> #define MACRO1 25 int main(void) { #ifdef MACRO1 // test whether MACRO1 is defined... printf("\nMACRO1 Defined with value [%d]\n", MACRO1); #endif return 0; }
So in the code above, a value of 25 is given to the macro MACRO1. When the code above is run, we see the following output :
$ ./macro MACRO1 Defined with value [25]
So we see that the macro name (MACRO1) was replaced by 25 in the code.
NOTE: For more on the compilation process, please refer to the article : Journey of a C program to Linux executable
Defining macros with values from command line
Not only the macros can be defined from command line (as shown in one of the sections above) but also they can be given values from command line. Lets take the following example :
#include <stdio.h> int main(void) { #ifdef MACRO1 // test whether MACRO1 is defined... printf("\nMACRO1 Defined with value [%d]\n", MACRO1); #endif return 0; }
In the code above, the macro MACRO1 is being tested and its value is being used but it is not defined anywhere. Lets define it from the command line :
$ gcc -Wall -DMACRO1=25 macro.c -o macro $ ./macro MACRO1 Defined with value [25]
So we see that through the command line option -D[Macroname]=[Value] it was made possible.
Macros with piece of code as their values
As discussed in the introduction part, macros can also contain small piece of code as their values. Those piece of code which are very small and are being used repetitively in the code are assigned to macros. For example :
#include <stdio.h> #define MACRO(x) x * (x+5) int main(void) { #ifdef MACRO // test whether MACRO1 is defined... printf("\nMACRO Defined...\n"); #endif int res = MACRO(2); printf("\n res = [%d]\n", res); return 0; }
- So, In the code above we defined a parametrized macro that accepts a value and has a small piece of code associated with it.
- This macro is being used in the code to calculate value for the variable ‘res’.
When the above code is compiled and run, we see :
$ ./macro MACRO Defined... res = [14]
So we see that a parametrized macro (that has a small piece of code logic associated with it) was used to calculate the value for ‘res’.
Comments on this entry are closed.
Just a suggestion. In the last example replace the macro in this way:
#define MACRO(x) (x) * ((x)+5)
Explaining that the x should be put between brackets to avoid errors like this one:
yourMACRO(3+2) -> 3+2*(3+2+5)=23
myMACRO(3+2)-> (3+2)*((3+2)+5)=50
Can you also discuss about string concatenation with Macro, as well as dynamic code generations with Macros.
Very good article !!!
May I know that if we redefine a macro with new value, which is already defined in source file with a value, by command-line (as told in post), then why we get the value provided in source file rather than command-line ? and how to redefine it by value specified by command-line ??
Thanks
and please provide more information regarding macros like macro operators in another post, if possible..
Hi,
Thanks a lot,
if possible, explain macro operators in next post
Great Article,
It would be great if you provide some more examples.
The macro is used to comparing with 2 or more various like this
#define max( (a), (b) ) (a) > (b) ? (a) : (b)
I hope it is useful
string concatenation:
#define concat(x,y) x ## y
#include
#define FIRST 7
#define LAST 5
#define ALL FIRST + LAST
int main()
{
printf(“%d”, ALL*ALL);
return ALL;
}
What will be the output of the above program….
Option:
1. 47
2. 144
3. 35
4. 12
Please give the appropriate answer with explanation..
Hi Ansarul,
The output for ur code is 47.
bcoz “ALL” means “FIRST”+”LAST” is 7+5
so, the expression ALL*ALL is defined as 7+5*7+5 =7+35+5=47 (According to Operator precedence, first multiplication takes place after that addition takes place.)
Thanks a lot supraja……
I also hav some other queries…..will be posting very soon….hope i will get the very positive output from you……again thanx a lot……
#include
#define PRODUCT(x) (x*x)
int main()
{
int i=3,j,k,l;
j=PRODUCT(i+1);
k=PRODUCT(i++);
l=PRODUCT(++i);
printf(“%d%d%d%d”,i,j,k,l);
return o;
}
plz provide ad answer wit xplanation..thanks:)
very nice explaination
its awesome yaar………u have explain everything very well……..and make it very understanble
The following is my answer, please validate and provide alternate solution if this is wrong.
j=(i+1)*(i+1)
j=4*4=16
// Evaluate from right to left or left to right
k=(i++)*(i++)
k=4*3=12
new value of i now is 5.
l=(++i)*(++i)
l=7*6
l=42
why do we use macros when functions are there?
@mrudula
Question :
#include
#define PRODUCT(x) (x*x)
int main()
{
int i=3,j,k,l;
j=PRODUCT(i+1);
k=PRODUCT(i++);
l=PRODUCT(++i);
printf(“%d%d%d%d”,i,j,k,l);
return 0;
}
Solution :
Values of I will be changed during the program execution.
I=3,5,7
J=(3+1*3+1)=3+3+1=7
K=(3*3)=9
L=(7*7)=49
So final values of I,J,K,L will be 7,7,9,49
this is the most simple and best explanation and worth reading article about macros I ever came across in the internet