Embedded Interview Questions with Answers | Part 5
Macro is most powerful & dangerous resource of c language. If it used in the proper way then it can increase the readability and performance. Else it can cause the debugging issue which is difficult to solve.
Important fact about MACRO(s) in C:
It has many Advantages and Disadvantages. Before going to that part, we will just have a look to a simple macro definition.
Simple Macro Definition:
#define NO_OF_ITEMS 10
This definition will replace NO_OF_ITEMS with 10 incomplete code before compilation as it is pre-processor directive.
Now let take different macro definition:
Textual Replacement | Macro Function
#define SQUARE(x) (x * x)
Ideal function of this macro is to perform the square of the number. But now let's see why it can cause a problem. We will check its usage in different ways:
Example: 1
int b = 10;
a = SQUARE(b); //This works fine.
Example: 2
a = SQUARE(5+4); // Don't give Square value of 9
Expand like this:
5+4 * 5+4 =
5+ 20 + 4 =
29
Now change the MACRO Definition to:
#define SQUARE(x) ((x) * (x))
Now try to access macro using:
Example: 2
a = SQUARE(5+4); // Give Square of 9 //Works fine
As macro is doing textual replacement, it is always good practice to cover the each parameter with opening and closing braces in a macro to avoid any misleading error in output. It would not give you compilation error so sometimes it is very difficult to track back the error in a bigger code where you have many source files.
Type Checking in MACRO:
There will be no type checking MACRO. You can pass any type of argument it will fail and crash run time if it can not handle such inputs in macro.
To understand the behavior of macro syntax and behavior have a look at below code & output of the code:
Code Example:
#include <stdio.h>
#define MAX_1 10
#define MAX_2 {10} //No compilation Error
#define SQUARE_1(x) (x*x)
#define SQUARE_2(x) {x*x}
#define PRINT_1(str) {printf("%s\n",str);}
#define PRINT_2(str) printf("%s\n",str)
#define PRINT_3(x) printf("%d\n",x);
#define PRINT_4(x) (printf("%d\n",x);)
#define PRINT_5(x) (printf("%d\n",x))
#define PRINT_6(x) {printf("%d\n",x);}
int main() {
// your code goes here
int a = 5, b = 10;
char ch = 3;
float f = 4.1;
long l = 300;
double d = 200;
PRINT_1("KAPIL");
PRINT_2("THAKAR");
SQUARE_1(5);
//SQUARE_2(5); // Compilation Error
//PRINT_1(SQUARE_1(5)); //Run time Error
//PRINT_2(SQUARE_1(5)); //Run time Error
PRINT_3(SQUARE_1(5));
PRINT_3(SQUARE_1(3+2));
PRINT_3(SQUARE_1(MAX_1));
//PRINT_3(SQUARE_1(MAX_2)); //Compilation Error
//PRINT_4(SQUARE_1(MAX_1));
/*
prog.cpp:36:2: note: in expansion of macro 'PRINT_4'
PRINT_4(SQUARE_1(MAX_1));
^
prog.cpp:11:38: error: expected primary-expression before ')' token
#define PRINT_4(x) (printf("%d\n",x);)
^
*/
PRINT_5(SQUARE_1(MAX_1)); //Removed ; from PRINT_4
PRINT_5(SQUARE_1(a)); //Removed ; from PRINT_4
PRINT_5(SQUARE_1(b)); //Removed ; from PRINT_4
PRINT_5(SQUARE_1(ch)); //Removed ; from PRINT_4
PRINT_5(SQUARE_1(d)); //Removed ; from PRINT_4
PRINT_5(SQUARE_1(f)); //Removed ; from PRINT_4
PRINT_5(SQUARE_1(l)); //Removed ; from PRINT_4
return 0;
}
OutPut:
KAPIL THAKAR
25
11
100
100
25
100
9
0
536870912
90000
Important fact about MACRO(s) in C:
- Macro is pre-processor directive. (#define)
- Macro is used to define the constant variable.
- Macro can be used as the replacement of small function to increase the speed of execution.
- Macro will increase the size of the code as it will be replaced everywhere you use it.
- Due to macro, a speed of execution will increase. Due to there is no overhead of calling and return from function.
- Macro will increase the readability.
- Sometimes macro will give you re-usability, as changing at one place will change the value everywhere in code.
- Alternative of macro is to use the const variable.
- Macro is difficult to debug as it will be replaced at pre-processing stage and which will not be reflecting in your debugging window, so certainly you can't add it in watch window which will make it very difficult to debug.
- Macro does not have type checking, which is possible with inline function. Due to this fact it will be always better to cover each part of macro with parenthesis to avoid any problems
- Macro doesn't contain any size once you define, it will occupy the size wherever you use it.
- Macro can't be restricted within block scope, which is possible with const.
It has many Advantages and Disadvantages. Before going to that part, we will just have a look to a simple macro definition.
Simple Macro Definition:
#define NO_OF_ITEMS 10
This definition will replace NO_OF_ITEMS with 10 incomplete code before compilation as it is pre-processor directive.
Now let take different macro definition:
Textual Replacement | Macro Function
#define SQUARE(x) (x * x)
Ideal function of this macro is to perform the square of the number. But now let's see why it can cause a problem. We will check its usage in different ways:
Example: 1
int b = 10;
a = SQUARE(b); //This works fine.
Example: 2
a = SQUARE(5+4); // Don't give Square value of 9
Expand like this:
5+4 * 5+4 =
5+ 20 + 4 =
29
Now change the MACRO Definition to:
#define SQUARE(x) ((x) * (x))
Now try to access macro using:
Example: 2
a = SQUARE(5+4); // Give Square of 9 //Works fine
As macro is doing textual replacement, it is always good practice to cover the each parameter with opening and closing braces in a macro to avoid any misleading error in output. It would not give you compilation error so sometimes it is very difficult to track back the error in a bigger code where you have many source files.
Type Checking in MACRO:
There will be no type checking MACRO. You can pass any type of argument it will fail and crash run time if it can not handle such inputs in macro.
To understand the behavior of macro syntax and behavior have a look at below code & output of the code:
Code Example:
#include <stdio.h>
#define MAX_1 10
#define MAX_2 {10} //No compilation Error
#define SQUARE_1(x) (x*x)
#define SQUARE_2(x) {x*x}
#define PRINT_1(str) {printf("%s\n",str);}
#define PRINT_2(str) printf("%s\n",str)
#define PRINT_3(x) printf("%d\n",x);
#define PRINT_4(x) (printf("%d\n",x);)
#define PRINT_5(x) (printf("%d\n",x))
#define PRINT_6(x) {printf("%d\n",x);}
int main() {
// your code goes here
int a = 5, b = 10;
char ch = 3;
float f = 4.1;
long l = 300;
double d = 200;
PRINT_1("KAPIL");
PRINT_2("THAKAR");
SQUARE_1(5);
//SQUARE_2(5); // Compilation Error
//PRINT_1(SQUARE_1(5)); //Run time Error
//PRINT_2(SQUARE_1(5)); //Run time Error
PRINT_3(SQUARE_1(5));
PRINT_3(SQUARE_1(3+2));
PRINT_3(SQUARE_1(MAX_1));
//PRINT_3(SQUARE_1(MAX_2)); //Compilation Error
//PRINT_4(SQUARE_1(MAX_1));
/*
prog.cpp:36:2: note: in expansion of macro 'PRINT_4'
PRINT_4(SQUARE_1(MAX_1));
^
prog.cpp:11:38: error: expected primary-expression before ')' token
#define PRINT_4(x) (printf("%d\n",x);)
^
*/
PRINT_5(SQUARE_1(MAX_1)); //Removed ; from PRINT_4
PRINT_5(SQUARE_1(a)); //Removed ; from PRINT_4
PRINT_5(SQUARE_1(b)); //Removed ; from PRINT_4
PRINT_5(SQUARE_1(ch)); //Removed ; from PRINT_4
PRINT_5(SQUARE_1(d)); //Removed ; from PRINT_4
PRINT_5(SQUARE_1(f)); //Removed ; from PRINT_4
PRINT_5(SQUARE_1(l)); //Removed ; from PRINT_4
return 0;
}
OutPut:
KAPIL THAKAR
25
11
100
100
25
100
9
0
536870912
90000
Post a Comment