Macros vs Functions
Last Updated :
22 Jun, 2022
A macro is a name given to a block of C statements as a pre-processor directive. Being a pre-processor, the block of code is communicated to the compiler before entering into the actual coding (main () function). A macro is defined with the pre-processor directive. Macros are pre-processed which means that all the macros would be processed before your program compiles. However, functions are not preprocessed but compiled.
See the following example of Macro:
C
#include<stdio.h>
#define NUMBER 10
int main()
{
printf ( "%d" , NUMBER);
return 0;
}
|
C++
#include<iostream>
#define NUMBER 10
using namespace std;
int main()
{
cout<<NUMBER;
return 0;
}
|
Output:
10
See the following example of Function:
C
#include<stdio.h>
int number()
{
return 10;
}
int main()
{
printf ( "%d" , number());
return 0;
}
|
C++
#include<iostream>
using namespace std;
int number()
{
return 10;
}
int main()
{
cout<<number();
return 0;
}
|
Output:
10
Now compile them using the command:
gcc –E file_name.c
This will give you the executable code as shown in the figure:
This shows that the macros are preprocessed while functions are not.
In macros, no type checking(incompatible operand, etc.) is done and thus use of macros can lead to errors/side-effects in some cases. However, this is not the case with functions. Also, macros do not check for compilation error (if any). Consider the following two codes:
Macros:
C++
#include <iostream>
using namespace std;
#define CUBE(b) b*b*b
int main()
{
cout << CUBE(1 + 2);
return 0;
}
|
C
#include<stdio.h>
#define CUBE(b) b*b*b
int main()
{
printf ( "%d" , CUBE(1+2));
return 0;
}
|
Output: Unexpected output
7
Note: This macro is expanded as below
CUBE(1+2) === 1+2*1+2*1+2 which is equal to 7 [correct but unexpected result depending upon the execution of the mathematical operators]
To fix this we need to replace #define CUBE(b) b*b*b as #define CUBE(b) (b)*(b)*(b). With updated macro, CUBE(1+2) will be expanded as
CUBE(1+2) === (1+2)*(1+2)*(1+2) which is equal to 27 [correct and expected result]
Functions:
C++
#include <iostream>
using namespace std;
int cube( int a);
int main()
{
cout << cube(1 + 2) << endl;
}
int cube( int a)
{
return a * a * a;
}
|
C
#include<stdio.h>
int cube( int a)
{
return a*a*a;
}
int main()
{
printf ( "%d" , cube(1+2));
return 0;
}
|
Output: As expected
27
- Macros are usually one liner. However, they can consist of more than one line, Click here to see the usage. There are no such constraints in functions.
- The speed at which macros and functions differs. Macros are typically faster than functions as they don’t involve actual function call overhead.
Conclusion:
Macros are no longer recommended as they cause following issues. There is a better way in modern compilers that is inline functions and const variable. Below are disadvantages of macros:
a) There is no type checking
b) Difficult to debug as they cause simple replacement.
c) Macro don’t have namespace, so a macro in one section of code can affect other section.
d) Macros can cause side effects as shown in above CUBE() example.
Macro |
Function |
Macros are Preprocessed |
Functions are Compiled |
No Type Checking is done in Macro |
Type Checking is Done in Function |
Using Macro increases the code length |
Using Function keeps the code length unaffected |
Use of macro can lead to side effect at later stages |
Functions do not lead to any side effect in any case |
Speed of Execution using Macro is Faster |
Speed of Execution using Function is Slower |
Before Compilation, macro name is replaced by macro value |
During function call, transfer of control takes place |
Macros are useful when small code is repeated many times |
Functions are useful when large code is to be written |
Macro does not check any Compile-Time Errors |
Function checks Compile-Time Errors |
See following for more details on macros:
Interesting facts about Macros and Preprocessors
Share your thoughts in the comments
Please Login to comment...