Препроцессор языка Си предоставляет возможность компиляции с условиями. Это допускает возможность существования различных версий одного кода. Обычно, такой подход используется для настройки программы под платформу компилятора, состояние (отлаживаемый код может быть выделен в результирующем коде), или возможность проверки подключения файла строго один раз.
В общем случае, программисту необходимо использовать конструкцию наподобие этой:
Такая «защита макросов» предотвращает двойное подключение заголовочного файла путем проверки существования этого макроса, который имеет то же самое имя, что и заголовочный файл. Определение макроса FOO_H происходит, когда заголовочный файл впервые обрабатывается препроцессором. Затем, если этот заголовочный файл вновь подключается, FOO_H уже определен, в результате чего препроцессор пропускает полностью текст этого заголовочного файла.
То же самое можно сделать, включив в заголовочный файл директиву:
#pragma once
Условия препроцессора можно задавать несколькими способами, например:
#ifdef x...#else...#endif
или
#if x...#else...#endif
Этот способ часто используется в системных заголовочных файлах для проверки различных возможностей, определение которых может меняться в зависимости от платформы; например, библиотека Glibc использует макросы с проверкой особенностей с целью проверить, что операционная система и оборудование их (макросы) корректно поддерживает при неизменности программного интерфейса.
Большинство современных языков программирования не используют такие возможности, больше полагаясь на традиционные операторы условия if...then...else..., оставляя компилятору задачу извлечения бесполезного кода из компилируемой программы.