Условная компиляция (#ifdef/#ifndef/#else/#endif)

Директивы условной компиляции позволяют включать и исключать фрагменты кода из процесса компиляции. Директивы #ifdef и #ifndef обозначает начало управляемого ими фрагмента кода. Завершается фрагмент с помощью директивы #endif. В простейшем случае синтаксис #ifdef следующий:

#ifdef макро_идентификатор
   инструкции
#endif

Если макрос с указанным идентификатором определен выше по коду с помощью #define, то данный фрагмент кода будет участвовать в компиляции. В противном случае, он исключается. Помимо макросов, определенных в прикладном коде, среда предоставляет набор предопределенных констант, в частности флаги _RELEASE и _DEBUG (см. раздел Предопределенные константы): их имена также можно проверять в директивах условной компиляции.

Расширенная форма #ifdef позволяет указать два фрагмента кода: первый будет включен, если макро-идентификатор определен, а второй — в его отсутствии. Для этого между #ifdef и #endif вставляется разделитель фрагментов — #else.

#ifdef макро_идентификатор
   инструкции_истина
#else
   инструкции_ложь
#endif

Директива #ifndef работает аналогично, но фрагменты включаются и исключаются по обратной логике: если указанный в заголовке макрос не определен, компилируется первый фрагмент, а если определен — компилируется второй.

Например, в зависимости от наличия макроподстановки DEMO, мы можем вызывать или не вызывать функцию расчета чисел Фибоначчи.

#ifdef DEMO
   Print("Fibo is disabled in the demo");
#else
   FillFibo();
#endif

В данном случае при включенном режиме DEMO вместо вызова функции в журнал выводилось бы сообщение, но поскольку в скрипте Preprocessor.mq5 и всех включенных файлах нет определения #define DEMO, компиляция идет по ветке #else, то есть в исполняемый ex5-файл попадает вызов функции FillFibo.

Директивы можно делать вложенными.

#ifdef _DEBUG
   Print("Debugging");
#else
   #ifdef _RELEASE
      Print("Normal run");
   #else
      Print("Undefined mode!");
   #endif
#endif