Директивы #if, #elif, #else и #endif
Директивы препроцессора, управляющие компиляцией частей исходного файла.
#if ifCondition ... |
---|
[#elif elifCondition ...] |
[#else ...] |
#endif |
Параметры
Элемент | Описание |
---|---|
ifCondition |
Основное условие для оценки. Если этот параметр имеет ненулевое значение, весь текст между этой директивой #if и следующим экземпляром директивы #elif, #else или #endif сохраняется в блоке преобразования; В противном случае последующий исходный код не сохраняется. Условие может использовать оператор препроцессора, определенный, чтобы определить, определена ли определенная константа препроцессора или макрос; Это эквивалентно использованию директивы #ifdef . Ограничения на значение параметра ifCondition см. в разделе Примечания . |
elifCondition [необязательно] |
Другое условие для оценки. Если параметр ifCondition и все предыдущие директивы #elif имеют нулевое значение и этот параметр имеет ненулевое значение, весь текст между этой директивой #elif и следующим экземпляром директивы #elif, #else или #endif сохраняется в единице преобразования; В противном случае последующий исходный код не сохраняется. Условие может использовать оператор препроцессора, определенный, чтобы определить, определена ли определенная константа препроцессора или макрос; Это эквивалентно использованию директивы #ifdef . Ограничения на значение параметра elifCondition см. в разделе Примечания . |
Комментарии
Каждая директива #if в исходном файле должна соответствовать закрывающей директиве #endif. Между директивами #if и #endif может отображаться любое количество директив #elif, но допускается не более одной директивы #else. Директива #else, если она есть, должна быть последней директивой перед #endif. Директивы условной компиляции, содержащиеся во включаемых файлах, должны соответствовать тем же условиям.
Директивы #if, #elif, #else и #endif могут вложиться в текстовые части других директив #if. Каждая вложенная директива #else, #elif или #endif принадлежит к ближайшей предыдущей директиве #if.
Если никакие условия не оцениваются как ненулевое значение, препроцессор выбирает текстовый блок после директивы #else. Если предложение #else опущено и никакие условия не оцениваются как ненулевое значение, блок текста не выбирается.
Параметры ifCondition и elifCondition в значительной степени соответствуют следующим требованиям.
- Выражения условной компиляции обрабатываются как длинные значения со знаком , и эти выражения оцениваются по тем же правилам, что и выражения в C++.
- Выражения должны иметь целочисленный тип и могут содержать только целочисленные константы, символьные константы и оператор defined.
- Выражения не могут использовать оператор sizeof или оператор приведения типов.
- Целевая среда может быть не в состоянии представлять все диапазоны целых чисел.
- Преобразование представляет тип int совпадает с типом long, а unsigned int — таким же, как unsigned long.
- Транслятор может преобразовывать символьные константы в набор кодовых значений, отличающийся от набора для целевой среды. Для определения свойств целевой среды проверьте значения макросов из файла LIMITS.H в приложении, собранном для целевой среды.
- Выражение не должно выполнять никаких запросов среды и не должно зависеть от конкретной реализации на целевом компьютере.
Примеры
В этом разделе приведены примеры использования директив препроцессора условной компиляции.
Использование определенного оператора
В следующем примере показано использование определенного оператора . Если определен идентификатор CREDIT, то компилируется вызов кредитной функции. Если определен идентификатор DEBIT, то компилируется вызов дебетной функции. Если ни тот из идентификаторов не определен, вызов функции printerror компилируется. Обратите внимание, что "КРЕДИТ" и "кредит" являются различными идентификаторами в C и C++, так как их варианты различаются.
#if defined(CREDIT)
credit();
#elif defined(DEBIT)
debit();
#else
printerror();
#endif
Использование вложенных директив #if
В следующем примере показано, как вложить директивы #if. В этом примере предполагается, что ранее была определена символьная константа DLEVEL. Директивы #elif и #else используются для выбора одного из четырех вариантов на основе значения DLEVEL. Константе STACK присваивается значение 0, 100 или 200 в зависимости от определения DLEVEL. Если значение DLEVEL больше 5, то STACK не определяется.
#if DLEVEL > 5
#define SIGNAL 1
#if STACKUSE == 1
#define STACK 200
#else
#define STACK 100
#endif
#else
#define SIGNAL 0
#if STACKUSE == 1
#define STACK 100
#else
#define STACK 50
#endif
#endif
#if DLEVEL == 0
#define STACK 0
#elif DLEVEL == 1
#define STACK 100
#elif DLEVEL > 5
display( debugptr );
#else
#define STACK 200
#endif
Используется для включения файлов заголовков
Условная компиляция обычно используется для предотвращения нескольких включений одного и того же файла заголовка. В C++, где классы часто определяются в файлах заголовков, можно использовать конструкции условной компиляции, чтобы предотвратить создание нескольких определений. В следующем примере определяется, определена ли символьная константная EXAMPLE_H. Если это так, файл уже включен и не требует повторной обработки; В противном случае определяется константная EXAMPLE_H, указывающая на этот пример. H уже обработан.
#if !defined( EXAMPLE_H )
#define EXAMPLE_H
class Example
{
...
};
#endif // !defined( EXAMPLE_H )