• C Programming Video Tutorials

Macros in C



Macros in C are the names given to specific constant values or code statements which are replaced with their value/code before the compilation processor. C Macros are defined using the #define preprocessor directive.

Macros are useful for code reusability, defining constant values, defining inline functions, and conditional compilations.

The following are the different types of C macros that we are going to cover in this tutorial –

  • Object-like Macros
  • Function-like Macros
  • Chained Macros
  • Variadic Macros
  • Predefined Macros

Object-like Macros

A macro that defines a constant is an object-like macro.

Syntax

It is done with the following syntax −

#define name value

Example of Object-like Macros

In the following example, we are defining an object-like macro −

#include <stdio.h>

// Defining macros
#define PI 3.14
#define MAX 10

int main() {
   // Printing the values
   printf("Value of PI = %d\n", PI);
   printf("Value of MAX = %d\n", MAX);

   return 0;
}

Function-like Macro

To define a function-like macro, you use the same "#define" directive, but you put a pair of parentheses immediately after the macro name, with one or more arguments. Such a macro is expanded only when its name appears with a pair of parentheses after it.

When the preprocessor expands such a macro, it incorporates the specified arguments in the replacement text. The function-like macros are often called Macros with parameters (or arguments).

Syntax

A function-like macro is defined as follows −

#define macro_name([parameter_list]) replacement_text

Example of Function-like Macros

An example of function-like macro is given below −

#include <stdio.h>

#define square(x) ((x) * (x))

int main(){

   int x = 5;
   printf("x: %d \tSquare of x: %d", x, square(x));
   return 0;
}

Output

When you run this code, it will produce the following output −

x: 5 	Square of x: 25

Rules for Defining Function-like Macros

Some rules of defining a function also apply to macros −

  • A macro can be defined without arguments
  • A macro can be defined with a fixed number of arguments
  • A macro can be defined with a variable number of arguments

For example, when you use such a macro, the comma-separated argument list must contain as many arguments as there are parameters in the macro definition.

Function-like Macros without Arguments

A function-like macro may also be defined without arguments.

Example 1

The following example shows how you can use a macro without arguments −

#include <stdio.h>

#define MESSAGE() printf("Hello World");

int main() {

   int x = 5;
   MESSAGE();
   return 0;
}

Output

Run the code and check its output −

Hello World

Some standard libraries also provide macro definitions in it. For example, the getchar() macro when expanded, implements the getc() function as follows −

#define getchar() getc(stdin)

Similarly, the putchar() macro encapsulates the putc() function −

#define putchar(x) putc(x, stdout)

Example 2

The following program defines a macro named as LOOP(x) and runs a for loop for the number of times as its argument −

#include <stdio.h>

#define LOOP(x) {\
   for (int i = 1; i <= x; i++)\
   printf("Iteration no: %d\n", i);\
}

int main() {

   int x = 3;
   LOOP(x);
}

Output

When you run this code, it will produce the following output −

Iteration no: 1
Iteration no: 2
Iteration no: 3

Chained Macros

When we have a macro nested inside another macro, they are called Chained Macros.

Example of Chained Macros

The following example shows how you can use chained macros −

#include <stdio.h>

#define PI 3.142
#define CIRCUMFERENCE(x) (2*PI*x)

int main(){

   int x = 5;
   printf("Circumference of a circle with radius %d is %f", x, CIRCUMFERENCE(x));
   return 0;
}

Output

When you run this code, it will produce the following output −

Circumference of a circle with radius 5 is 31.420000

Variadic Macros

You can also define a macro with variable number of arguments or variadic macros. A macro with variable-length argument is a feature that enables a macro to accept any number of arguments. You can pass positional as well as keyword arguments to a macro.

When a variadic macro is defined, the ellipsis (…) is given as an argument to capture variable number of arguments. To use variadic macros, the ellipsis may be specified as the final formal argument in a macro definition. This sequence of tokens replaces the identifier __VA_ARGS__ in the macro body wherever it appears.

The __VA_ARGS__ is replaced by all of the arguments that match the ellipsis, including commas between them. Note that the variadic macros can be used only in the C99 compatible C compilers and above.

Example of Variadic Macros

Take a look at the following example −

#include <stdio.h>

#define MAX_ARGS 5		// Define maximum number of allowed arguments
#define ARGS(x, ...) do {\
   printf("%d\n", ##__VA_ARGS__); \
} while (0)

int main() {

   ARGS(1, 2, 3); 		// 3 arguments
   ARGS(1, 2, 3, 4, 5, 6);	// 6 arguments 
   return 0;
}

Output

Run the code and check its output −

2
2

Predefined Macros

ANSI C defines a number of macros. Although each one is available for use in programming, the predefined macros should not be directly modified.

Macro Description
__DATE__ The current date as a character literal in "MMM DD YYYY" format.
__TIME__ The current time as a character literal in "HH:MM:SS" format.
__FILE__ This contains the current filename as a string literal.
__LINE__ This contains the current line number as a decimal constant.
__STDC__ Defined as 1 when the compiler complies with the ANSI standard.

Example

The following example demonstrates how you can use the predefined macros in a C program −

#include <stdio.h>

int main() {

   printf("File :%s\n", __FILE__ );
   printf("Date :%s\n", __DATE__ );
   printf("Time :%s\n", __TIME__ );
   printf("Line :%d\n", __LINE__ );
   printf("ANSI :%d\n", __STDC__ );
}

Output

When you run this code, it will produce the following output −

File: main.c
Date: Mar 6 2024
Time: 20:12:19
Line: 8
ANSI: 1
Advertisements