#define directive in C


Reading time: 20 minutes | Coding time: 5 minutes

#define is a preprocessor directive in C which is used to define macros. Macros are code framents which has been given a name. The main use of define directive is to make the implementation more intuitive by defining our own structural replacements for actual implementation.

Syntax:

#define MACRO_NAME code_fragment 

Example:

#define INTEGER int

In the above code segment, we have defined a new macro named INTEGER which is representing int (a valid code fragment). When INTEGER is used, it will be replaced by int during the preprocessing step of compilation. When int is used, it is remain unchanged.

#define can be used for any valid code fragment. Let us see the complete C example with the above define for INTEGER macro.

#include <stdio.h>

#define INTEGER int

int main() {
    INTEGER DATA = 1;
    printf("%d", DATA);
	return 0;
}

In the code, every INTEGER will be replaced by int in the preprocessing step. The output will be:

1

defining the same macro twice will give an error. We will see this through an example. Check this example where we have defined the macro DATA twice.

#include <stdio.h>

#define DATA opengenus
#define DATA og

int main() {
    int DATA = 1;
    printf("%d", opengenus);
	return 0;
}

Compile it using the command:

gcc opengenus.c

The compilation error will be:

opengenus.c:4:0: warning: "DATA" redefined
 #define DATA og
 ^
opengenus.c:3:0: note: this is the location of the previous definition
 #define DATA opengenus
 ^
opengenus.c: In function 'main':
opengenus.c:8:18: error: 'opengenus' undeclared (first use in this function)
     printf("%d", opengenus);
                  ^
opengenus.c:8:18: note: each undeclared identifier is reported only once for each function it appears in

Use define for multi-line code

We can define multi-line code in a macro. To do this, we need to add the backslash (\) at the end of each line (except the last line). After code expansion (or macro expansion), all code will appear in the same line but separated by space. This should not be an issue.

Example:

#include <stdio.h>

#define INTEGER int \
data = 1;

int main() {
    INTEGER
    printf("%d", data);
	return 0;
}

Output:

1

If you do not use the backslash, it will give an error. Consider the above code without backslash:

#include <stdio.h>

#define INTEGER int 
data = 1;

int main() {
    INTEGER
    printf("%d", data);
	return 0;
}

Compilation error:

opengenus.c:4:1: warning: data definition has no type or storage class
 data = 1;
 ^
opengenus.c:4:1: warning: type defaults to 'int' in declaration of 'data' [-Wimplicit-int]
opengenus.c: In function 'main':
opengenus.c:8:12: error: expected declaration specifiers or '...' before string constant
     printf("%d", data);
            ^
opengenus.c:8:18: error: expected declaration specifiers or '...' before 'data'
     printf("%d", data);
                  ^

Use define for a structure

We can define a structure in a macro as follows:

#include <stdio.h>

#define INTEGER struct Point \
{ \
   int x, y;\
} 

int main() {
    INTEGER DATA = {1, 1};
    printf("%d", DATA.x);
	return 0;
}

Output will be:

1

Use define carefully

Defining a macro with the macro name as a keyword or it the programmer is unaware of the macro, it may give arise to compilation or even runtime error. For this, it is advised to follow MACRO naming conventions.

Example of defining a macro with name as int.

#include <stdio.h>

#define int char*

int main() {
    int DATA = "opengenus";
    printf("%s", DATA);
	return 0;
}

In this code, the programmer intends to define an integer variable named DATA but due to the macro, it is changed to a character array and ignores the issue.

Consider this example which will give an error:

#include <stdio.h>

#define int integer

int main() {
    int DATA = 1;
    printf("%d", DATA);
	return 0;
}

The problem is that the macro maybe defined in an header file and the programmer may never find the actual cause of the error. The compilation error for the above code will be:

opengenus.c:3:13: error: unknown type name 'integer'
 #define int integer
             ^
opengenus.c:5:1: note: in expansion of macro 'int'
 int main() {
 ^
opengenus.c: In function 'main':
opengenus.c:3:13: error: unknown type name 'integer'
 #define int integer
             ^
opengenus.c:6:5: note: in expansion of macro 'int'
     int DATA = 1;
     ^

It is advised to define macros with name with all capital letters and two underscore at the end like:

#define INTEGER__ int

With this knowledge, you are go to use #define in C anyway you want to.

Enjoy!