Директивы #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 см. в разделе "Примечания".

Remarks

Каждая директива #if в исходном файле должна соответствовать закрывающей директиве #endif. Любое количество директив #elif может отображаться между директивами #if и #endif, но допускается не более одной директивы #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 . Обратите внимание, что "CREDIT" и "кредит" являются отдельными идентификаторами в 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 определяется, чтобы указать, что EXAMPLE. H уже обработан.

#if !defined( EXAMPLE_H )
#define EXAMPLE_H

class Example
{
...
};

#endif // !defined( EXAMPLE_H )

См. также раздел

Директивы препроцессора (DirectX HLSL)