logo
volkov / 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 (т.е. операторы С++ и

команды препроцессора) игнорируется. Текст, относящийся к первой

команде с ненулевым значением выражения подлежит обычной препроцессорной

обработке и трансляции. Если значения всех выражений, указанных в #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 идентификатор

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

но реализация может накладывать ограничение на глубину вложенности

этих конструкций.