What Differences are there Between Macros and Functions in C Language

«
»
Question: What are Differences Between Macros and Functions in C Language?

Answer: Macros are like functions but don’t act like functions. For ex.,

#define MAX(a,b)   ((a) > (b) ? (a) : (b))

When used in program, preprocessor substitutes macro MAX(a,b) with it’s definition wherever it appears in program. For ex.,

advertisement
int main(void)
{   
    int x = 10, y = 10;
 
    MAX(x, y);
    MAX(3.4, 5.6);
    MAX(15, 4);
 
    return 0;
}

After above program is preprocessed, it outputs as,

 
int main(void)
{
    int x = 10, y = 10;
 
    ((x) > (y) ? (x) : (y));
    ((3.4) > (5.6) ? (3.4) : (5.6));
    ((15) > (4) ? (15) : (4));
 
    return 0;
}

In order to get preprocessed output, type on Linux shell prompt the following cmd

cpp filename.c > filename.i

where cpp is c preprocessor, fienme.c is which C file you wish to preprocess, filename.i is filename in which you wish preprocessed output to be written. ‘>’ symbol creates the file fiename.i and writes the output into it. You can then use vim or other editor to see the contents of the file.

advertisement

Notice that preprocessor inserted macro definition wherever macro MAX appeared and inserted values for macro arguments in the definition. Notice here that same MAX computed the larger of two integers, two floats, etc. For same task, no separate macros for specific types of data are required. Hence macros are typeless. Further, macros are faster than functions as there’s no overhead of calling and return as in functions.

How would it be if you had used functions insted? Let’s implement this in a simple C program below,

#include <stdio.h>
 
void sum2ints(const int, const int);
void sum2floats(const float, const float);
void sum2doubles(const double, const double);
 
int main(void)
{
    int x = 10, y = 10;
 
    sum2ints(x, y);
    sum2floats(3.4, 5.6);
    sum2doubles(15, 4);
 
    return 0;
}
 
void sum2ints(const int a, const int b)
{
    printf("sum of two integers %d and %d is %d\n", a + b);
}
 
<pre lang="C" cssfile="hk1_style">
void sum2floats(const float a, const float b)
{
    printf("sum of two floats %.2f and %.2f is %.2f\n", a + b);
}
 
void sum2doubles(const double, const double)
{
    printf("sum of two doubles %.2lf and %.2lf is %.2lf\n", a + b);
}

Notice here that even if functions above all perform same task, these were required to be specific for types of values they processed. There’s just single copy of each function is defined and is used every time when function is called. In addition, they don’t increase the size of program. But each function exerts overhead of being called and returned. Therefore, macros are efficient only when they are very short just one or two lines of code.

Let’s see what happens when macro arguments having side-effects, for ex.,

#define MAX(a,b) ((a) > (b) ? (a) : (b))
int main(void)
{
    int x = 10, y = 10, z;
 
    z = MAX(x++, y++);
 
    printf(" x = %d, y = %d, z = %d", x, y, z);
 
    return 0;
}

Observe the Output below,

advertisement
x = 11, y = 12, z = 11

While x incremented once, y incremented twice once during comparison and once after :. Let’s understand this by substituting MAX(x++, y++) in the exp.

    z = MAX(x++, y++);

with it’s definition as

    z = ((x++) > (y++) ? (x++) : (y++));

Firstly, both x and y incremented to 11 each. Since

    11 > 11

is false. exp. after : executed and assigned value 11 to z before incremented y again to 12.

advertisement

Side-effect is a permanent effect caused by evaluating the expression. Had these argments been passed in function, would have they caused the same side-effect? No, since arguments are evaluated before they are passed to function.

One more difference is that macros execute faster and they don’t exert overhead of calling and returning as functions do.

Sanfoundry Global Education & Learning Series – 1000 C Tutorials.

If you wish to look at all C Tutorials, go to C Tutorials.

Participate in the Sanfoundry Certification contest to get free Certificate of Merit. Join our social networks below and stay updated with latest contests, videos, internships and jobs!
advertisement
advertisement
advertisement
Manish Bhojasia, a technology veteran with 20+ years @ Cisco & Wipro, is Founder and CTO at Sanfoundry. He is Linux Kernel Developer & SAN Architect and is passionate about competency developments in these areas. He lives in Bangalore and delivers focused training sessions to IT professionals in Linux Kernel, Linux Debugging, Linux Device Drivers, Linux Networking, Linux Storage, Advanced C Programming, SAN Storage Technologies, SCSI Internals & Storage Protocols such as iSCSI & Fiber Channel. Stay connected with him @ LinkedIn