In this blog, you will learn how to write a multiline macro in C Language. I have already written an article on C macros but here we will discuss only how to write the multiline macro in C. It is my recommendation if you are going to use macro first time in your program, you should read the “C Macros” blog post first.
Generally, define macros that span over a single line. But however, there are some situations when you need to define a macro that spans over multiple lines. But it is my recommendation that you should use the inline function specifier (supported from C99) besides using the multi-line macros whenever possible.
We can create a multiline macros in C using the backslash-newline (\
). You need to use \
to escape each line break which you want to be part of the macro. Let’s see some example code,
#include <stdio.h> #define LIST 10, \ 20, \ 30 int main() { //Initialized array int arr[] = { LIST }; printf("arr[0] = %d\n",arr[0]); printf("arr[1] = %d\n",arr[1]); printf("arr[2] = %d\n",arr[2]); return 0; }
OutPut:
arr[0] = 10
arr[1] = 20
arr[2] = 30
But there are issues with multiline macros if you will not handle them carefully. You could be in trouble. Let’s understand it.
//Multi-Line Macros #define PRINT_MSG(MSG) printf(MSG " AMLENDRA\n"); \ printf(MSG " ATICLEWORLD\n"); \ printf(MSG " KUMAR\n");
The above-mentioned macro will print the three messages whenever it will call. But this can cause problems if someone uses the macro in a context that demands a single statement. See the below code.
#include <stdio.h> #define PRINT_MSG(MSG) printf(MSG " AMLENDRA\n"); \ printf(MSG " ATICLEWORLD\n"); \ printf(MSG " KUMAR\n"); int main() { int i = 3; while (i--) PRINT_MSG("hello"); return 0; }
When you will run this code, you will expect the below output.
hello AMLENDRA hello ATICLEWORLD hello KUMAR hello AMLENDRA hello ATICLEWORLD hello KUMAR hello AMLENDRA hello ATICLEWORLD hello KUMAR
But you will not get the desired output you will get the below output.
hello AMLENDRA hello AMLENDRA hello AMLENDRA hello ATICLEWORLD hello KUMAR
You can resolve this problem by wrapping the macro statements in curly braces. See the below code.
#include <stdio.h> #define PRINT_MSG(MSG) {\ printf(MSG " AMLENDRA\n");\ printf(MSG " ATICLEWORLD\n");\ printf(MSG " KUMAR\n");\ } int main() { int i = 3; while (i--) PRINT_MSG("hello"); return 0; }
Output:
But wrapping the macro statements does not work always it also create issue some times. In some contexts, this will cause compile-time errors. See the below code,
#include <stdio.h> #define PRINT_MSG(MSG) {\ printf(MSG " AMLENDRA\n");\ printf(MSG " ATICLEWORLD\n");\ printf(MSG " KUMAR\n");\ } int main() { if(1) PRINT_MSG("Hello"); else printf("Learning from aticleworld\n"); return 0; }
Output:
Explanation:
We are getting the compile-time error due to an extra semicolon after the if block. The above code expands in the below format.
int main() { if(1) { printf(MSG " AMLENDRA\n"); printf(MSG " ATICLEWORLD\n"); printf(MSG " KUMAR\n"); }; //<<< This extra semicolon is issue here else printf("Learning from aticleworld\n"); return 0; }
You can resolve the issue by using the do-while false loop (pseudo-loop). This executes the body of the “loop” exactly once. I have removed the semicolon from while(0), intended to solve the above problem. TheĀ do-while macro look like this:
#define PRINT_MSG(MSG) do{\ printf(MSG " AMLENDRA\n");\ printf(MSG " ATICLEWORLD\n");\ printf(MSG " KUMAR\n");\ }while(0) // << intentionally not including semicolon (;) here
After using the do-while false loop your code will work and you will not get the compile-time error.
#include <stdio.h> #define PRINT_MSG(MSG) do{\ printf(MSG " AMLENDRA\n");\ printf(MSG " ATICLEWORLD\n");\ printf(MSG " KUMAR\n");\ }while(0) int main() { if(1) PRINT_MSG("Hello"); else printf("Learning from aticleworld"); return 0; }
Output:
Hello AMLENDRA
Hello ATICLEWORLD
Hello KUMAR
If your compiler has refused to inline-expand any function containing a loop, you can use the below macro.
#define PRINT_MSG(MSG) if(1){\ printf(MSG " AMLENDRA\n");\ printf(MSG " ATICLEWORLD\n");\ printf(MSG " KUMAR\n");\ }else (void)0 // << intentionally not including semicolon (;) here
The complete code will look like this.
#include <stdio.h> #define PRINT_MSG(MSG) if(1){\ printf(MSG " AMLENDRA\n");\ printf(MSG " ATICLEWORLD\n");\ printf(MSG " KUMAR\n");\ }else (void)0 int main() { if(1) PRINT_MSG("Hello"); else printf("Learning from aticleworld"); return 0; }
Output:
Hello AMLENDRA
Hello ATICLEWORLD
Hello KUMAR