Препроцесор С/С++ — програмний інструмент, який використовується в мовах програмування C та C++, препроцесор, що змінює код програми для подальшої компіляції й збірки.

Мова препроцесора C/C++ не є повною за Тюрінгом хоча б тому, що за допомогою директив неможливо змусити препроцесор «зависнути».

Директиви ред.

Директивою препроцесора називається рядок у коді, який має такий вигляд #ключове_слово параметри. Є чітко визначений список ключових слів:

  • define — Задає макровизначення (макроси) або константу
  • undef — Скасовує попереднє визначення
  • include — Вставляє текст з зазначеного файлу (імпортує)
  • if — Здійснює умовну компіляцію при істинності константного виразу
  • ifdef — Здійснює умовну компіляцію, якщо константа визначена
  • ifndef — Здійснює умовну компіляцію при невизначеності константи
  • else — Гілка умовної компіляції при хибності висловлювання
  • elif — Гілка умовної компіляції, утворена злиттям else та if
  • endif — Кінець гілки умовної компіляції
  • line — Препроцесор змінює номер поточного рядка й ім'я файлу для компіляції
  • error — Висвітлення повідомлення з зупинки компіляції
  • pragma — Дію, що залежить від конкретної реалізації компілятора
  • warning — Висвітлення повідомлення без зупинки компіляції
  • порожнє слово — пуста дія

Опис директив ред.

Константи та макроси #define ред.

Константи та макроси препроцесора використовуються для визначення невеликих фрагментів коду. Зазвичай константи визначаються за допомогою великих літер.

// константа
#define BUFFER_SIZE 1024
#define PI 3.14
// макрос
#define NUMBER_OF_ARRAY_ITEMS(array) (sizeof(array)/sizeof(*(array)))

Кожна константа і кожен макрос замінюються відповідним їм визначенням. Макроси мають параметри, схожі на функції, використовуються для зменшення коду.

Приклад визначення макроса max, який приймає два аргументи: a і b та повертає більше з двох число:

#define max( a, b ) ( (a) > (b) ? (a) : (b) )

Макрос викликається як звичайна функція:

z = max(x, y);

Після заміни макроса код виглядатиме так:

z = ((x) > (y) ? (x) : (y));

Директива #include ред.

При виявленні директив #include "..."  або #include <...>, де «…» — ім'я файлу, препроцесор читає вміст зазначеного файлу, виконує директиви й заміни (підставлення).

Для #include "..."пошук файлу виконується в цій теці й теках, зазначених в командному рядку компілятора. Для #include <...> пошук файлу виконується в теках, що містять файли стандартної бібліотеки (шлях до цих тек залежать від компілятора).

Файли, що включаються зазвичай містять:

  • оголошення функцій;
  • оголошення глобальних змінних;
  • визначення інтерфейсів;
  • визначення типів даних;
  • структури
  • та інше.

Директива #includeзазвичай вказується на початку файлу (в заголовку), тому включаються файли називаються заголовками.

Приклад включення файлів зі стандартної бібліотеки мови C:

#include <math.h> // імпортування математичних функцій(стандартна бібліотека)
#include <foo.h> // імпортування файлу не зі стандартної бібліотеки

Використання препроцесора вважається неефективним з наступних причин:

  • кожен раз при включенні файлів виконуються директиви й заміни (підставляння); компілятор міг би зберігати результати препроцесорування для використання в майбутньому;
  • множинні включення одного файлу доводиться запобігати вручну за допомогою директив умовної компіляції; компілятор міг би виконувати цю задачу самостійно.

Починаючи з 1970-х років стали з'являтися способи, якими замінено включення файлів. У мовах Java і Common Lisp використовуються пакети (ключове слово package) (див. Package в Java), в мові Паскаль — англ.  units (ключові слова unitі uses), у мовах ModulaOCamlDHaskell і Python — модулі. Використовуються ключові слова moduleі import.

Посилання ред.