0% found this document useful (0 votes)
27 views8 pages

Preprocessor Directives Summary

The document discusses C preprocessor directives. It explains that #include is used to include header files, #define is used for macro definitions, #if/#elif/#else/#endif are used for conditional compilation, and other directives like #error, #line, #pragma are used to generate errors, set line numbers, and implement compiler-specific features. Function-like macros perform text substitution while normal functions have type checking and don't increase code size.

Uploaded by

mahamd saied
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
27 views8 pages

Preprocessor Directives Summary

The document discusses C preprocessor directives. It explains that #include is used to include header files, #define is used for macro definitions, #if/#elif/#else/#endif are used for conditional compilation, and other directives like #error, #line, #pragma are used to generate errors, set line numbers, and implement compiler-specific features. Function-like macros perform text substitution while normal functions have type checking and don't increase code size.

Uploaded by

mahamd saied
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 8

🗺

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"

define: replaces a symbol with a number or a string, known as macro definition.

ex: #define PI (3.14159)

The preprocessor does simple text replacement in macro definitions, in which


the preprocessor literally replaces a symbol with the symbol definition, even if
the definition includes characters, semicolons, strings or even empty spaces.

We can use math expressions as a macro, ex: #define MULTIPLY (2 * 3)

Multi-line macro:

#\
define \
MAX \
50

Function like macros :

#include <stdio.h>
#define SUM(NUM1, NUM2) (NUM1 + NUM2)

int main()
{

Preprocessor Directives 1
printf("The sum is equal to: %i", SUM(1, 2));
}

The sum is equal to 3

Output of the preprocessed file:

The macro function does not specify a specific data type.

When using comments on multiline macro function we should use multiline


comment ( /* */ ) and put the comment before the new line ( \ ) to avoid
any errors.

Applications

we can use function like macros to make bit-wise operation much easier,

#include <stdint.h>
#include <stdio.h>

#define SET_BIT(VAR, BIT_POSITION) ((VAR) |= (1 << (BIT_POSITION)))


#define CLEAR_BIT(VAR, BIT_POSITION) ((VAR) &= ~(1 << (BIT_POSITION)))
#define TOGGLE_BIT(VAR, BIT_POSITION) ((VAR) ^= (1 << (BIT_POSITION)))

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

Difference between function-like macros and normal functions

Macros are preprocessed, functions are compiled.

Macros has no type checking, functions has.

Macros are more difficult to debug, because the cause simple replacement.

Macros has faster execution speed.

Macros increase the code length, functions are useful when a large code is
written.

Macros does not check for any Compile-Time errors.

Conditional directive #if :

/* 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 .

We can use #if to remove unnecessary code:

#if 0
printf("Hello");
printf(" World");
#endif

The code between #if and #endif is removed in the preprocessing stage.

Checking if a Macro is defined using #ifdef :

#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.

__LINE__ : prints out the line number.

__DATE__ : prints out the current date.

Preprocessor Directives 4
we can find more macros by just typing __ and rest will appear in the IDE.

Error directive #error

#ifdef TEST
#error "TEST is defined"
#endif

#error is used to create error message while preprocessing a file.

#error have to be inside a a conditional directive or it will cause an error every time
we preprocess the file.

Line directive #line

#line 20 "main.c"
printf("Current line is %i", __LINE__);
printf("Current line is %i", __LINE__);

/* #line FileNumber "FileName.c" */

Current line is 20
Current line is 21

Used to make a user defined line number.


The output in the preprocessor:

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);

#pargma is compiler dependent.

We can use #pragma to prevent the user from using a specific identifier.

#include <stdio.h>

#pragma GCC poison printf

int main()
{
printf("Current line is %i\n", __LINE__);
printf("Current line is %i\n", __LINE__);
}

main.c: In function ‘main’:


main.c:7:5: error: attempt to use poisoned "printf"
7 | printf("Current line is %i\n", __LINE__);
| ^
main.c:8:5: error: attempt to use poisoned "printf"
8 | printf("Current line is %i\n", __LINE__);
| ^

We can use it also to make warnings.

#include <stdio.h>

#pragma GCC warning "main.c is used"

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"
| ^~~~~~~~~~~~~~~~

Using #pragma to make errors.

#include <stdio.h>

#pragma GCC error "main.c is used"

int main()
{
printf("Current line is %i\n", __LINE__);
printf("Current line is %i\n", __LINE__);
}

main.c:3:19: error: main.c is used


3 | #pragma GCC error "main.c is used"
| ^~~~~~~~~~~~~~~~

#if defined(..)

/* EX 1 */
#define H
#if defined(H)
void function1(void);
#else
void function2(void);

/* EX 2 */
#define H1
#define H2

#if !defined(H1) && defined(H2)


#error "error"
#endif

How to turn any parameter to string using # operator in macro functions

#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

/* Output in the preprocessed file */

# 5 "main.c"
int main()
{
printf("test" "\n");
}

Preprocessor Directives 8

You might also like