Для організації умовної компіляції використовують директиви препроцесора #if, #else, #elif, #endif, #ifdef, #ifndef а також операцію defined. Ці директиви призначені для вибіркової компіляції окремих частин програми. Вони дають змогу опустити компіляцію тих фрагментів програми, які не відповідають заданим умовам. Умовну компіляцію використовують при налагодженні програм і в випадках, коли існує декілька спеціальних версій загальної програми.
Синтаксично директиви умовної компіляції, які вказують, чи буде компілюватись заданий фрагмент програми, подібні до оператора if, вони мають скорочену і повну форму. Скорочена форма директиви #if:
#if константний_вираз
фрагмент_програми
#endif
Повна форма директиви #if:
#if константний_вираз
фрагмент_програми_1
#else
фрагмент_програми_2
#endif
Константний вираз директиви #if, який задає умову компіляції, може складатися з констант або ідентифікаторів макропідстановок. У разі використання короткої форми запису директиви умовної компіляції, фрагмент програми між #if і #endif буде компілюватися тільки за умови, що значення константного виразу істинне (відмінне від нуля). У разі використання повної форми запису цієї директиви, буде компілюватися або фрагмент програми 1 (якщо значення виразу істинне), або фрагмент програми 2 (якщо значення виразу хибне). Кінець фрагменту програми, який підлягає умовній компіляції, задає директива #endif. В наступному прикладі до програми будуть підключатися різні заголовні файли, залежно від обраної мови:
#define UKR 1
#define ENG 2
#define LANG UKR
#if LANG == UKR
#include "ukr.h"
#else
#include "eng.h"
#endif
Директива #elif є спрощеним варіантом конструкції #else - #if. Синтаксис її такий самий, як і директиви #if:
#elif константний_вираз
фрагмент_програми
Якщо заданий константний вираз є істинним, то записаний далі фрагмент програми передається на компіляцію, інакше він пропускається. За допомогою цієї директиви зручно створювати послідовності перевірок:
#if константний_вираз_1
фрагмент_програми_1
#elif константний_вираз_2
фрагмент_програми_2
…
#elif константний_вираз_k
фрагмент_програми_k
#else
альтернативний_фрагмент_програми
#endif
В цьому випадку першим перевіряється константний вираз 1. Якщо він хибний, то перевіряється вираз 2 і так далі, доки не буде знайдено істинний вираз. Якщо такий вираз знайдено, то відповідний фрагмент програми передається на компіляцію, перевірка умов завершується. Якщо всі вирази хибні, то компілюватись буде фрагмент програми, що відповідає варіанту #else, за умови, що він є в програмі. Таким чином, на компіляцію буде передано тільки один, або не передано жодного, з усіх фрагментів програми, що підлягають умовній компіляції.
#define UKR 1
#define ENG 2
#define RUS 3
#define LANG ENG
#if LANG == UKR
#include "ukr.h"
#elif LANG == ENG
#include "eng.h"
#elif LANG == RUS
#include "rus.h"
#else
#include "ukr.h"
#endif
В цьому прикладі можна обрати один з трьох варіантів мови, залежно від вибору будуть підключені різні заголовні файли. За замовчуванням буде підключений файл ukr.h.