Справочное руководство по C++

R.16.5 Условная трансляция.

С помощью препроцессора можно организовать условную трансляцию программы. Синтаксически это задается следующим образом:

Условное:

 часть-if части-elif opt часть-else opt строка-endif.

Часть-if:

 строка-if текст.

Строка-if:

 # if выражение-константа.

 # ifdef идентификатор.

 # ifndef идентификатор.

Части-elif:

 строка-elif текст.

 части-elif строка-elif текст.

Строка-elif:

 # elif выражение-константа.

Часть-else:

 строка-else текст.

Строка-else:

 # else.

Строка-endif:

 # endif.

Константные выражения в #if и #elif (если эти части есть) вычисляются в порядке их задания в тексте до тех пор, пока одно из них не окажется отличным от нуля. Операторы С++, следующие за строкой, в которой выражение оказалось равным нулю, не транслируются. Команды препроцессора, идущие за этой строкой игнорируются. После того, как найдена команда с ненулевым значением выражения, текст всех последующих частей #elif и #else (т.е. операторы C++ и команды препроцессора) игнорируется. Текст, относящийся к первой команде с ненулевым значением выражения подлежит обычной препроцессорной обработке и трансляции. Если значения всех выражений, указанных в #if и #elif, оказались равными нулю, тогда обычной обработке подлежит текст, относящийся к #else.

В выражении-константе, которое встретилось в #if или #elif можно использовать унарную операцию defined, причем в двух вариантах:

Defined идентификатор.

Или.

Defined (идентификатор).

Если эта операция применяется к идентификатору, который был определен с помощью команды #define, и если это определение не было отменено командой #undef, то результат равен 1, иначе результат равен 0. Сам идентификатор defined нельзя переопределить, нельзя и отменить его определение.

После применения операций defined происходит раскрытие всех всех макроопределений, имеющихся в константном выражении см. §R.16.3. В результате должно получиться целочисленное выражение-константа, отличающееся от определения в §R.5.19 тем, что типы int и unsigned int рассматриваются как long и unsigned long соответственно, а кроме того в этом выражении не должно быть операций приведения, sizeof или элемента перечисления.

Управляющая строка.

#ifdef идентификатор.

Эквивалентна строке.

#if defined идентификатор.

А управляющая строка.

#ifndef идентификатор.

Эквивалентна строке.

#if !defined идентификатор.

Конструкции, задающие условную трансляцию, могут быть вложенными, но реализация может накладывать ограничение на глубину вложенности этих конструкций.