How to Define C Macros (C Example Using #define and #ifdef)

by Himanshu Arora on May 29, 2012

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’.


Linux Sysadmin Course Linux provides several powerful administrative tools and utilities which will help you to manage your systems effectively. If you don’t know what these tools are and how to use them, you could be spending lot of time trying to perform even the basic administrative tasks. The focus of this course is to help you understand system administration tools, which will help you to become an effective Linux system administrator.
Get the Linux Sysadmin Course Now!

If you enjoyed this article, you might also like..

  1. 50 Linux Sysadmin Tutorials
  2. 50 Most Frequently Used Linux Commands (With Examples)
  3. Top 25 Best Linux Performance Monitoring and Debugging Tools
  4. Mommy, I found it! – 15 Practical Linux Find Command Examples
  5. Linux 101 Hacks 2nd Edition eBook Linux 101 Hacks Book

Bash 101 Hacks Book Sed and Awk 101 Hacks Book Nagios Core 3 Book Vim 101 Hacks Book

{ 17 comments… read them below or add one }

1 HoX May 29, 2012 at 1:47 am

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

2 Shakil May 29, 2012 at 2:29 am

Can you also discuss about string concatenation with Macro, as well as dynamic code generations with Macros.

3 Kuldeep May 29, 2012 at 3:22 am

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

4 Kuldeep May 29, 2012 at 3:28 am

and please provide more information regarding macros like macro operators in another post, if possible..

5 Jalal Hajigholamali May 29, 2012 at 11:34 am

Hi,
Thanks a lot,

if possible, explain macro operators in next post

6 Anonymous May 29, 2012 at 10:54 pm

Great Article,

It would be great if you provide some more examples.

7 Martin June 8, 2012 at 12:28 am

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

8 selvam August 2, 2012 at 8:44 am

string concatenation:

#define concat(x,y) x ## y

9 Ansarul Islam Laskar September 26, 2012 at 8:52 am

#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..

10 supraja November 1, 2012 at 6:53 am

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.)

11 Ansarul November 1, 2012 at 1:00 pm

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……

12 mrudula July 25, 2013 at 5:31 am

#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:)

13 shradha September 7, 2013 at 4:14 am

very nice explaination

14 himanshu vikram singh September 30, 2013 at 7:05 am

its awesome yaar………u have explain everything very well……..and make it very understanble

15 Srikanth March 24, 2014 at 1:12 am

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

16 Anonymous March 25, 2014 at 1:15 am

why do we use macros when functions are there?

17 kartik April 24, 2014 at 3:50 am

@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

Leave a Comment

Previous post:

Next post: