Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Hygienic Macros in C
Here we will see the Hygienic Macros in C. We know the usage of macros in C. But sometimes, macros do not return the desired results because of accidental capture of identifiers, where macro variables interfere with variables in the calling code.
Syntax
#define MACRO_NAME(params) do { /* avoid variable name conflicts */ } while(0)
Problem: Non-Hygienic Macro
If we see the following code, we can see that it is not working properly because the macro uses variable name 'a' which conflicts with the program's variable −
#include <stdio.h>
#define INCREMENT(i) do { int a = 0; ++i; } while(0)
int main(void) {
int a = 10, b = 20;
//Call the macros two times for a and b
INCREMENT(a);
INCREMENT(b);
printf("a = %d, b = %d<br>", a, b);
return 0;
}
After preprocessing the code will be like this −
#include <stdio.h>
#define INCREMENT(i) do { int a = 0; ++i; } while(0)
int main(void) {
int a = 10, b = 20;
//Call the macros two times for a and b
do { int a = 0; ++a; } while(0) ; // increments local 'a', not the outer 'a'
do { int a = 0; ++b; } while(0) ; // increments 'b' correctly
printf("a = %d, b = %d<br>", a, b);
return 0;
}
a = 10, b = 21
Here we can see the value is not updated for 'a' because the macro's local variable 'a' shadows the outer variable.
Solution: Hygienic Macro
Hygienic macros are macros whose expansion guarantees that they do not create accidental capture of identifiers. Here we use a unique variable name 't' that does not interfere with the calling code −
#include <stdio.h>
#define INCREMENT(i) do { int t = 0; ++i; } while(0)
int main(void) {
int a = 10, b = 20;
//Call the macros two times for a and b
INCREMENT(a);
INCREMENT(b);
printf("a = %d, b = %d<br>", a, b);
return 0;
}
a = 11, b = 21
Key Points
- Use unique variable names in macros to avoid identifier capture
- The
do-while(0)idiom creates a proper statement block - Choose variable names unlikely to conflict with user code
Conclusion
Hygienic macros prevent variable name conflicts by using unique identifiers within the macro expansion. This ensures macros work correctly regardless of the calling code's variable names.
