The C Preprocessor
How to use the C Preprocessor
The preprocessor is a tool that helps us a lot when programming with C. It is part of the C Standard, just like the language, the compiler and the standard library.
It parses our program and makes sure that the compiler gets all the things it needs before going on with the process.
What does it do, in practice?
For example, it looks up all the header files you include with the #include directive.
It also looks at every constant you defined using #define and substitutes it with its actual value.
That’s just the start, and I mentioned those 2 operations because they are the most common ones. The preprocessor can do a lot more.
Did you notice #include and #define have a # at the beginning? That’s common to all the preprocessor directives. If a line starts with #, that’s taken care by the preprocessor.
Conditionals
One of the things we can do is to use conditionals to change how our program will be compiled, depending on the value of an expression.
For example we can check if the DEBUG constant is 0:
#include <stdio.h>
const int DEBUG = 0;
int main(void) {
#if DEBUG == 0
printf("I am NOT debugging\n");
#else
printf("I am debugging\n");
#endif
}
Symbolic constants
We can define a symbolic constant:
#define VALUE 1
#define PI 3.14
#define NAME "Flavio"
When we use NAME or PI or VALUE in our program, the preprocessor replaces its name with the value, before executing the program.
Symbolic constants are very useful because we can give names to values without creating variables at compilation time.
Macros
With #define we can also define a macro. The difference between a macro and a symbolic constant is that a macro can accept an argument and typically contains code, while a symbolic constant is a value:
#define POWER(x) ((x) * (x))
Notice the parentheses around the arguments, a good practice to avoid issues when the macro is replaced in the precompilation process.
Then we can use it in our code like this:
printf("%u\n", POWER(4)); //16
The big difference with functions is that macros do not specify the type of their arguments or return values, which might be handy in some cases.
If defined
We can check if a symbolic constant or a macro is defined using #ifdef:
#include <stdio.h>
#define VALUE 1
int main(void) {
#ifdef VALUE
printf("Value is defined\n");
#else
printf("Value is not defined\n");
#endif
}
We also have #ifndef to check for the opposite (macro not defined).
We can also use #if defined and #if !defined to do the same task.
It’s common to wrap some block of code into a block like this:
#if 0
#endif
to temporarily prevent it to run, or to use a DEBUG symbolic constant:
#define DEBUG 0
#if DEBUG
//code only sent to the compiler
//if DEBUG is not 0
#endif
Predefined symbolic constants you can use
The preprocessor also defines a number of symbolic constants you can use, identified by the 2 underscores before and after the name, including:
__LINE__translates to the current line in the source code file__FILE__translates to the name of the file__DATE__translates to the compilation date, in theMmm gg aaaaformat__TIME__translates to the compilation time, in thehh:mm:ssformat
download all my books for free
- javascript handbook
- typescript handbook
- css handbook
- node.js handbook
- astro handbook
- html handbook
- next.js pages router handbook
- alpine.js handbook
- htmx handbook
- react handbook
- sql handbook
- git cheat sheet
- laravel handbook
- express handbook
- swift handbook
- go handbook
- php handbook
- python handbook
- cli handbook
- c handbook
subscribe to my newsletter to get them
Terms: by subscribing to the newsletter you agree the following terms and conditions and privacy policy. The aim of the newsletter is to keep you up to date about new tutorials, new book releases or courses organized by Flavio. If you wish to unsubscribe from the newsletter, you can click the unsubscribe link that's present at the bottom of each email, anytime. I will not communicate/spread/publish or otherwise give away your address. Your email address is the only personal information collected, and it's only collected for the primary purpose of keeping you informed through the newsletter. It's stored in a secure server based in the EU. You can contact Flavio by emailing [email protected]. These terms and conditions are governed by the laws in force in Italy and you unconditionally submit to the jurisdiction of the courts of Italy.