Preprocesor jest podprogramem uruchamianym tuż przed rozpoczęciem właściwej kompilacji. Jego zadaniem jest tak sformatowanie źródła aby mogły zostać bez błędów przetworzone przez kompilator - zawierały wszystkie potrzebne deklaracje.
Większość plików źródłowych zawiera powtarzające się odwołania do funkcji/zmiennych/struktur znajdujących się w innych plikach. Aby kompilator wiedział co reprezentuje dana etykieta (nazwa funkcji/zmiennej/struktury), programista musi przynajmniej ją zadeklarować. W tym celu tworzone są pliki nagłówkowe - zwalniają programistę z obowiązku pisania powtarzających się deklaracji.
Dyrektywy są poleceniami dla preprocesora, które sterują jego zachowaniem. Posiadają następujący format:
# (musi być pierwszym niebiałym znakiem w linii; nie musi być odzielony odstępem od polecenia)define, undef, include, if, ifdef, ifndef, else, elif, endif, line, error, pragma)Przykładowa dyrektywa może wyglądać następująco:
# include <iostream>
Głównym zadaniem preprocesora jest wstawianie zawartości innych plików, definiowanie makr/stałych, które są następnie (przed kompilacją) zamieniane na faktyczne fragmenty kodu/wartości. Preprocesor może:
#if, #ifdef, #ifndef, #else, #elif oraz #endif)#include)#warning)#error)#line)
W zależności od implementacji (wersji), kompilator (lub preprocesor) może udostępniać dodatkowe opcje. Są one dostępne za pomocą dyrektywy #pragma. Dokumentacja kompilatora powinna zawierać listę oraz opis poleceń wspieranych przez tą dyrektywę.
| # oraz ## | manipuluje łańcuchami znaków |
| #define | definiuje stałe lub makra |
| #error | wyświetla błąd kompilacji |
| #if, #ifdef, #ifndef, #else, #elif, oraz #endif | operatory warunkowe |
| #include | wstawia zawartość podanego pliku |
| #line | ustawia informacje o linii i pliku |
| #pragma | przekazuje dodatkowe polecenia do kompilatora (zachowanie zależy od implementacji) |
| #undef | anuluje definicję stałych lub makr |
| Zmienne preprocesora | wartości generowane dynamiczne przez preprocesor |