Preprocessor Directives Summary
Preprocessor Directives Summary
Preprocessor Directives
include : includes the content of the header file included inside the source code
#include <..> Used to include libraries’ header files located in the compiler’s
path.
#include ".." Used to include user defined header file located in the project
folder, and if the header file is at another location we include the header file with
its absolute paths.
ex: #include "D:\Header files\app.h"
Multi-line macro:
#\
define \
MAX \
50
#include <stdio.h>
#define SUM(NUM1, NUM2) (NUM1 + NUM2)
int main()
{
Preprocessor Directives 1
printf("The sum is equal to: %i", SUM(1, 2));
}
Applications
we can use function like macros to make bit-wise operation much easier,
#include <stdint.h>
#include <stdio.h>
int main()
{
uint8_t var = 0x01; /* 0000 0001 */
printf("var = %i\n", var);
printf("var = %i\n", SET_BIT(var, 1)); /* 0000 0011 */
printf("var = %i\n", CLEAR_BIT(var, 1)); /* 0000 0001 */
Preprocessor Directives 2
printf("var = %i\n", TOGGLE_BIT(var, 1)); /* 0000 0011 */
return 0;
}
var = 1
var = 3
var = 1
var = 3
Macros are more difficult to debug, because the cause simple replacement.
Macros increase the code length, functions are useful when a large code is
written.
/* app.c */
void lcd_print(uint8_t data)
{
#if LCD_MODE == 4
lcd_print_4bit(data);
#elif LCD_MODE == 8
lcd_print_8bit(data);
#endif
}
/* lcd.h */
#include <stdint.h>
void lcd_print_4bit(uint8_t data);
void lcd_print_8bit(uint8_t data);
#define LCD_MODE = 4
The usage of the print function is determined by the LCD_MODE macro defined in
the included lcd.h library.
Preprocessor Directives 3
Every #if have to end with #endif .
#if 0
printf("Hello");
printf(" World");
#endif
The code between #if and #endif is removed in the preprocessing stage.
#ifdef LCD_MODE
printf("LCD_MODE is defined\n");
#endif
We can use File Guards to prevent problems resulting from including the same
header file multiple times, ex with lcd.h file.
#ifndef _LCD_H_
#define _LCD_H_
#include <stdint.h>
void lcd_print_4bit(uint8_t data);
void lcd_print_8bit(uint8_t data);
#define LCD_MODE 4
#endif
The preprocessor checks if _LCD_H_ is not defined, and if not defined, we define it, and if
we include this header file multiple times, only the first time will be preprocessed, and
the other times it will be neglected because _LCD_H_ is defined before.
Predefined Macros
__FILE__ : prints out the file name.
Preprocessor Directives 4
we can find more macros by just typing __ and rest will appear in the IDE.
#ifdef TEST
#error "TEST is defined"
#endif
#error have to be inside a a conditional directive or it will cause an error every time
we preprocess the file.
#line 20 "main.c"
printf("Current line is %i", __LINE__);
printf("Current line is %i", __LINE__);
Current line is 20
Current line is 21
Preprocessor Directives 5
#pragma Directive
We can use #pragma instead of the file guard to prevent multiple header file inclusion,
but the file guard is considered better practice.
#pragma once
void MotorMove(void);
We can use #pragma to prevent the user from using a specific identifier.
#include <stdio.h>
int main()
{
printf("Current line is %i\n", __LINE__);
printf("Current line is %i\n", __LINE__);
}
#include <stdio.h>
int main()
{
printf("Current line is %i\n", __LINE__);
printf("Current line is %i\n", __LINE__);
}
Preprocessor Directives 6
main.c:3:21: warning: main.c is used
3 | #pragma GCC warning "main.c is used"
| ^~~~~~~~~~~~~~~~
#include <stdio.h>
int main()
{
printf("Current line is %i\n", __LINE__);
printf("Current line is %i\n", __LINE__);
}
#if defined(..)
/* EX 1 */
#define H
#if defined(H)
void function1(void);
#else
void function2(void);
/* EX 2 */
#define H1
#define H2
#include <stdio.h>
Preprocessor Directives 7
#define PRINT(STRING) printf(#STRING "\n")
int main()
{
PRINT(test); // Even if the paramter is not in double quotes it is converted to a string
}
test
# 5 "main.c"
int main()
{
printf("test" "\n");
}
Preprocessor Directives 8